diff -r 450143d2d810 browser/components/Makefile.in
--- a/browser/components/Makefile.in	Fri Aug 24 15:28:46 2012 -0700
+++ b/browser/components/Makefile.in	Mon Sep 03 14:02:08 2012 +0300
@@ -41,6 +41,7 @@
   tabview \
   thumbnails \
   migration \
+  webcl \
   $(NULL)
 
 ifdef MOZ_SAFE_BROWSING
diff -r 450143d2d810 browser/components/build/Makefile.in
--- a/browser/components/build/Makefile.in	Fri Aug 24 15:28:46 2012 -0700
+++ b/browser/components/build/Makefile.in	Mon Sep 03 14:02:08 2012 +0300
@@ -33,6 +33,7 @@
 	-I$(srcdir)/../privatebrowsing/src \
 	-I$(srcdir)/../about \
 	-I$(srcdir)/../dirprovider \
+	-I$(srcdir)/../webcl/src \
 	$(NULL)
 
 ifeq ($(OS_ARCH),WINNT)
@@ -44,6 +45,7 @@
 	../privatebrowsing/src/$(LIB_PREFIX)privatebrowsing_s.$(LIB_SUFFIX) \
 	../about/$(LIB_PREFIX)browserabout_s.$(LIB_SUFFIX) \
 	../dirprovider/$(LIB_PREFIX)browserdir_s.$(LIB_SUFFIX) \
+	../webcl/src/$(LIB_PREFIX)webcl_s.$(LIB_SUFFIX) \
 	$(NULL)
 
 ifneq (,$(filter windows cocoa gtk2, $(MOZ_WIDGET_TOOLKIT)))
diff -r 450143d2d810 browser/components/build/nsModule.cpp
--- a/browser/components/build/nsModule.cpp	Fri Aug 24 15:28:46 2012 -0700
+++ b/browser/components/build/nsModule.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -7,6 +7,7 @@
 
 #include "nsBrowserCompsCID.h"
 #include "DirectoryProvider.h"
+#include "nsIScriptNameSpaceManager.h"
 
 #if defined(XP_WIN)
 #include "nsWindowsShellService.h"
@@ -24,6 +25,16 @@
 #include "nsFeedSniffer.h"
 #include "AboutRedirector.h"
 #include "nsIAboutModule.h"
+#include "WebCL.h"
+#include "WebCLPlatform.h"
+#include "WebCLDevice.h"
+#include "WebCLMemoryObject.h"
+#include "WebCLKernel.h"
+#include "WebCLProgram.h"
+#include "WebCLEvent.h"
+#include "WebCLCommandQueue.h"
+#include "WebCLContext.h"
+#include "WebCLSampler.h"
 
 #include "nsPrivateBrowsingServiceWrapper.h"
 #include "nsNetCID.h"
@@ -64,6 +75,27 @@
 #endif
 NS_DEFINE_NAMED_CID(NS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID);
 
+NS_GENERIC_FACTORY_CONSTRUCTOR (WebCL)
+NS_GENERIC_FACTORY_CONSTRUCTOR (WebCLPlatform)
+NS_GENERIC_FACTORY_CONSTRUCTOR (WebCLDevice)
+NS_GENERIC_FACTORY_CONSTRUCTOR (WebCLMemoryObject)
+NS_GENERIC_FACTORY_CONSTRUCTOR (WebCLKernel)
+NS_GENERIC_FACTORY_CONSTRUCTOR (WebCLProgram)
+NS_GENERIC_FACTORY_CONSTRUCTOR (WebCLEvent)
+NS_GENERIC_FACTORY_CONSTRUCTOR (WebCLCommandQueue)
+NS_GENERIC_FACTORY_CONSTRUCTOR (WebCLContext)
+NS_GENERIC_FACTORY_CONSTRUCTOR (WebCLSampler)
+NS_DEFINE_NAMED_CID (WEBCL_CID);
+NS_DEFINE_NAMED_CID (WEBCL_PLATFORM_CID);
+NS_DEFINE_NAMED_CID (WEBCL_DEVICE_CID);
+NS_DEFINE_NAMED_CID (WEBCL_MEMORYOBJECT_CID);
+NS_DEFINE_NAMED_CID (WEBCL_KERNEL_CID);
+NS_DEFINE_NAMED_CID (WEBCL_PROGRAM_CID);
+NS_DEFINE_NAMED_CID (WEBCL_EVENT_CID);
+NS_DEFINE_NAMED_CID (WEBCL_COMMANDQUEUE_CID);
+NS_DEFINE_NAMED_CID (WEBCL_CONTEXT_CID);
+NS_DEFINE_NAMED_CID (WEBCL_SAMPLER_CID);
+
 static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
     { &kNS_BROWSERDIRECTORYPROVIDER_CID, false, NULL, DirectoryProviderConstructor },
 #if defined(XP_WIN)
@@ -79,6 +111,16 @@
     { &kNS_SHELLSERVICE_CID, false, NULL, nsMacShellServiceConstructor },
 #endif
     { &kNS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID, false, NULL, nsPrivateBrowsingServiceWrapperConstructor },
+    { &kWEBCL_CID, false, NULL, WebCLConstructor },
+    { &kWEBCL_PLATFORM_CID, false, NULL, WebCLPlatformConstructor },
+    { &kWEBCL_DEVICE_CID, false, NULL, WebCLDeviceConstructor },
+    { &kWEBCL_MEMORYOBJECT_CID, false, NULL, WebCLMemoryObjectConstructor },
+    { &kWEBCL_KERNEL_CID, false, NULL, WebCLKernelConstructor },
+    { &kWEBCL_PROGRAM_CID, false, NULL, WebCLProgramConstructor },
+    { &kWEBCL_EVENT_CID, false, NULL, WebCLEventConstructor },
+    { &kWEBCL_COMMANDQUEUE_CID, false, NULL, WebCLCommandQueueConstructor },
+    { &kWEBCL_CONTEXT_CID, false, NULL, WebCLContextConstructor },
+    { &kWEBCL_SAMPLER_CID, false, NULL, WebCLSamplerConstructor },
     { NULL }
 };
 
@@ -113,12 +155,24 @@
     { NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID },
 #endif
     { NS_PRIVATE_BROWSING_SERVICE_CONTRACTID, &kNS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID },
+
+    { WEBCL_CONTRACTID, &kWEBCL_CID },
+    { WEBCL_PLATFORM_CONTRACTID, &kWEBCL_PLATFORM_CID },
+    { WEBCL_DEVICE_CONTRACTID, &kWEBCL_DEVICE_CID },
+    { WEBCL_MEMORYOBJECT_CONTRACTID, &kWEBCL_MEMORYOBJECT_CID },
+    { WEBCL_KERNEL_CONTRACTID, &kWEBCL_KERNEL_CID },
+    { WEBCL_PROGRAM_CONTRACTID, &kWEBCL_PROGRAM_CID },
+    { WEBCL_EVENT_CONTRACTID, &kWEBCL_EVENT_CID },
+    { WEBCL_COMMANDQUEUE_CONTRACTID, &kWEBCL_COMMANDQUEUE_CID },
+    { WEBCL_CONTEXT_CONTRACTID, &kWEBCL_CONTEXT_CID },
+    { WEBCL_SAMPLER_CONTRACTID, &kWEBCL_SAMPLER_CID },
     { NULL }
 };
 
 static const mozilla::Module::CategoryEntry kBrowserCategories[] = {
     { XPCOM_DIRECTORY_PROVIDER_CATEGORY, "browser-directory-provider", NS_BROWSERDIRECTORYPROVIDER_CONTRACTID },
     { NS_CONTENT_SNIFFER_CATEGORY, "Feed Sniffer", NS_FEEDSNIFFER_CONTRACTID },
+    { JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY, "WebCL", WEBCL_CONTRACTID },
     { NULL }
 };
 
diff -r 450143d2d810 browser/components/webcl/Makefile.in
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/Makefile.in	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,11 @@
+DEPTH		= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+DIRS = public src
+# TEST_DIRS += test
+
+include $(topsrcdir)/config/rules.mk
diff -r 450143d2d810 browser/components/webcl/public/IWebCL.idl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/IWebCL.idl	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,409 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \interface IWebCL
+ * Main WebCL component interface.
+ * This main WebCL component interface provides a handle to WebCL functionality
+ * and certain utilities, as well as a number of named constants providing
+ * compatibility with OpenCL.
+ */
+
+#include "nsISupports.idl"
+#include "nsISecurityCheckedComponent.idl"
+#include "nsIVariant.idl"
+#include "nsIArray.idl"
+
+#include "WebCL_types.idl"
+
+interface IWebCLContext;
+interface IWebCLDataObject;
+interface IWebCLUtils;
+interface IWebCLPlatform;
+
+
+[scriptable, uuid(8d1a0db2-94af-4333-9b55-9c516a1dbbea)]
+interface IWebCL : nsISecurityCheckedComponent
+{
+  /**
+   * Supported data types.
+   * This attribute lists the data types that are supported on info patameter
+   * and kernel argument explicit type conversions.
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  readonly attribute nsIVariant types;
+
+  /** The WebCL version information.
+   * This attribute contains the WebCL version as an array of 4 integers.
+   * Index 0 is major API version, 1 is minor API version, 2 is release number
+   * and 4 is the source repository revision number of 0 if the value was not
+   * available at build time.
+   */
+  [implicit_jscontext]
+  readonly attribute nsIVariant version;
+
+  // NOTE: Can't use IDL array (i.e. out count, [array size_is(count)] out retv)
+  //       since it always requires the count out parameter to be given as object,
+  //       even when it's not reallyused by the user.
+  // NOTE: Can't use nsIArray since it doesn't provide an interface that is compatible
+  //       with JS array.
+  /** Get the list of available platforms.
+   * \return Array of IWebCLPlatform instances as a JSArray wrapped in
+   *  an nsIVariant.
+   * \see clGetPlatformIDs
+   */
+  [implicit_jscontext]
+  nsIVariant getPlatformIDs ();
+
+  [implicit_jscontext]
+  nsIVariant getPlatforms ();
+
+  /** Create a new WebCL context. This function takes a list of devices.
+   * \param aProperties Array of properties. Names are integers, values can be integers or objects.
+   * \param aDevices Array of devices.
+   * \return A new WebCLContext instance.
+   * \see clCreateContext
+   */
+  [implicit_jscontext]
+  IWebCLContext createContext (in nsIVariant aProperties, in nsIVariant aDevices);
+
+  /** Create a new WebCL context. This function takes the type of devices to use.
+   * \param aProperties Array of properties. Names are integers, values can be integers or objects.
+   * \param aDeviceType The type of devices to use. All suitable devices available on the
+   *  platform will be used.
+   * \return A new WebCLContext instance.
+   * \see clCreateContextFromType
+   */
+  [implicit_jscontext]
+  IWebCLContext createContextFromType (in nsIVariant aProperties, in T_WebCLDeviceType aDeviceType);
+
+  /** Wait for the commands identified by the listed events to complete.
+   * The function will block the host thread untill finished.
+   * \param aEventList Array of IWebCLEvents.
+   * \see clWaitForEvents
+   */
+  [implicit_jscontext]
+  void waitForEvents (in nsIVariant aEventList);
+
+  /** Release the resources allocated by the OpenCL compiler.
+   * \see clUnloadCompiler
+   */
+  [implicit_jscontext]
+  void unloadCompiler ();
+
+  // Prevent the following constants from leaking to C++ header - the same
+  // identifiers are already available as defines from cl.h through wrapper.
+  // NOTE: This will cause warning which can be safely ignored.
+  // Sadly, doxygen gets confused and ignores the constants as well.
+%{C++
+  /*
+%}
+  const long CL_SUCCESS = 0;
+  const long CL_DEVICE_NOT_FOUND = -1;
+  const long CL_DEVICE_NOT_AVAILABLE = -2;
+  const long CL_COMPILER_NOT_AVAILABLE = -3;
+  const long CL_MEM_OBJECT_ALLOCATION_FAILURE = -4;
+  const long CL_OUT_OF_RESOURCES = -5;
+  const long CL_OUT_OF_HOST_MEMORY = -6;
+  const long CL_PROFILING_INFO_NOT_AVAILABLE = -7;
+  const long CL_MEM_COPY_OVERLAP = -8;
+  const long CL_IMAGE_FORMAT_MISMATCH = -9;
+  const long CL_IMAGE_FORMAT_NOT_SUPPORTED = -10;
+  const long CL_BUILD_PROGRAM_FAILURE = -11;
+  const long CL_MAP_FAILURE = -12;
+  const long CL_MISALIGNED_SUB_BUFFER_OFFSET = -13;
+  const long CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST = -14;
+  const long CL_INVALID_VALUE = -30;
+  const long CL_INVALID_DEVICE_TYPE = -31;
+  const long CL_INVALID_PLATFORM = -32;
+  const long CL_INVALID_DEVICE = -33;
+  const long CL_INVALID_CONTEXT = -34;
+  const long CL_INVALID_QUEUE_PROPERTIES = -35;
+  const long CL_INVALID_COMMAND_QUEUE = -36;
+  const long CL_INVALID_HOST_PTR = -37;
+  const long CL_INVALID_MEM_OBJECT = -38;
+  const long CL_INVALID_IMAGE_FORMAT_DESCRIPTOR = -39;
+  const long CL_INVALID_IMAGE_SIZE = -40;
+  const long CL_INVALID_SAMPLER = -41;
+  const long CL_INVALID_BINARY = -42;
+  const long CL_INVALID_BUILD_OPTIONS = -43;
+  const long CL_INVALID_PROGRAM = -44;
+  const long CL_INVALID_PROGRAM_EXECUTABLE = -45;
+  const long CL_INVALID_KERNEL_NAME = -46;
+  const long CL_INVALID_KERNEL_DEFINITION = -47;
+  const long CL_INVALID_KERNEL = -48;
+  const long CL_INVALID_ARG_INDEX = -49;
+  const long CL_INVALID_ARG_VALUE = -50;
+  const long CL_INVALID_ARG_SIZE = -51;
+  const long CL_INVALID_KERNEL_ARGS = -52;
+  const long CL_INVALID_WORK_DIMENSION = -53;
+  const long CL_INVALID_WORK_GROUP_SIZE = -54;
+  const long CL_INVALID_WORK_ITEM_SIZE = -55;
+  const long CL_INVALID_GLOBAL_OFFSET = -56;
+  const long CL_INVALID_EVENT_WAIT_LIST = -57;
+  const long CL_INVALID_EVENT = -58;
+  const long CL_INVALID_OPERATION = -59;
+  const long CL_INVALID_GL_OBJECT = -60;
+  const long CL_INVALID_BUFFER_SIZE = -61;
+  const long CL_INVALID_MIP_LEVEL = -62;
+  const long CL_INVALID_GLOBAL_WORK_SIZE = -63;
+  const long CL_INVALID_PROPERTY = -64;
+  const long CL_VERSION_1_0 = 1;
+  const long CL_VERSION_1_1 = 1;
+  const long CL_FALSE = 0;
+  const long CL_TRUE = 1;
+  const long CL_PLATFORM_PROFILE = 0x0900;
+  const long CL_PLATFORM_VERSION = 0x0901;
+  const long CL_PLATFORM_NAME = 0x0902;
+  const long CL_PLATFORM_VENDOR = 0x0903;
+  const long CL_PLATFORM_EXTENSIONS = 0x0904;
+  const long CL_DEVICE_TYPE_DEFAULT = (1<<0);
+  const long CL_DEVICE_TYPE_CPU = (1<<1);
+  const long CL_DEVICE_TYPE_GPU = (1<<2);
+  const long CL_DEVICE_TYPE_ACCELERATOR = (1<<3);
+  const unsigned long CL_DEVICE_TYPE_ALL = 0xFFFFFFFF;
+  const long CL_DEVICE_TYPE = 0x1000;
+  const long CL_DEVICE_VENDOR_ID = 0x1001;
+  const long CL_DEVICE_MAX_COMPUTE_UNITS = 0x1002;
+  const long CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS = 0x1003;
+  const long CL_DEVICE_MAX_WORK_GROUP_SIZE = 0x1004;
+  const long CL_DEVICE_MAX_WORK_ITEM_SIZES = 0x1005;
+  const long CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR = 0x1006;
+  const long CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT = 0x1007;
+  const long CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT = 0x1008;
+  const long CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG = 0x1009;
+  const long CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT = 0x100A;
+  const long CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE = 0x100B;
+  const long CL_DEVICE_MAX_CLOCK_FREQUENCY = 0x100C;
+  const long CL_DEVICE_ADDRESS_BITS = 0x100D;
+  const long CL_DEVICE_MAX_READ_IMAGE_ARGS = 0x100E;
+  const long CL_DEVICE_MAX_WRITE_IMAGE_ARGS = 0x100F;
+  const long CL_DEVICE_MAX_MEM_ALLOC_SIZE = 0x1010;
+  const long CL_DEVICE_IMAGE2D_MAX_WIDTH = 0x1011;
+  const long CL_DEVICE_IMAGE2D_MAX_HEIGHT = 0x1012;
+  const long CL_DEVICE_IMAGE3D_MAX_WIDTH = 0x1013;
+  const long CL_DEVICE_IMAGE3D_MAX_HEIGHT = 0x1014;
+  const long CL_DEVICE_IMAGE3D_MAX_DEPTH = 0x1015;
+  const long CL_DEVICE_IMAGE_SUPPORT = 0x1016;
+  const long CL_DEVICE_MAX_PARAMETER_SIZE = 0x1017;
+  const long CL_DEVICE_MAX_SAMPLERS = 0x1018;
+  const long CL_DEVICE_MEM_BASE_ADDR_ALIGN = 0x1019;
+  const long CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE = 0x101A;
+  const long CL_DEVICE_SINGLE_FP_CONFIG = 0x101B;
+  const long CL_DEVICE_GLOBAL_MEM_CACHE_TYPE = 0x101C;
+  const long CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE = 0x101D;
+  const long CL_DEVICE_GLOBAL_MEM_CACHE_SIZE = 0x101E;
+  const long CL_DEVICE_GLOBAL_MEM_SIZE = 0x101F;
+  const long CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE = 0x1020;
+  const long CL_DEVICE_MAX_CONSTANT_ARGS = 0x1021;
+  const long CL_DEVICE_LOCAL_MEM_TYPE = 0x1022;
+  const long CL_DEVICE_LOCAL_MEM_SIZE = 0x1023;
+  const long CL_DEVICE_ERROR_CORRECTION_SUPPORT = 0x1024;
+  const long CL_DEVICE_PROFILING_TIMER_RESOLUTION = 0x1025;
+  const long CL_DEVICE_ENDIAN_LITTLE = 0x1026;
+  const long CL_DEVICE_AVAILABLE = 0x1027;
+  const long CL_DEVICE_COMPILER_AVAILABLE = 0x1028;
+  const long CL_DEVICE_EXECUTION_CAPABILITIES = 0x1029;
+  const long CL_DEVICE_QUEUE_PROPERTIES = 0x102A;
+  const long CL_DEVICE_NAME = 0x102B;
+  const long CL_DEVICE_VENDOR = 0x102C;
+  const long CL_DRIVER_VERSION = 0x102D;
+  const long CL_DEVICE_PROFILE = 0x102E;
+  const long CL_DEVICE_VERSION = 0x102F;
+  const long CL_DEVICE_EXTENSIONS = 0x1030;
+  const long CL_DEVICE_PLATFORM = 0x1031;
+  const long CL_DEVICE_DOUBLE_FP_CONFIG = 0x1032;
+  const long CL_DEVICE_HALF_FP_CONFIG = 0x1033;
+  const long CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF = 0x1034;
+  const long CL_DEVICE_HOST_UNIFIED_MEMORY = 0x1035;
+  const long CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR = 0x1036;
+  const long CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT = 0x1037;
+  const long CL_DEVICE_NATIVE_VECTOR_WIDTH_INT = 0x1038;
+  const long CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG = 0x1039;
+  const long CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT = 0x103A;
+  const long CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE = 0x103B;
+  const long CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF = 0x103C;
+  const long CL_DEVICE_OPENCL_C_VERSION = 0x103D;
+  const long CL_FP_DENORM = (1<<0);
+  const long CL_FP_INF_NAN = (1<<1);
+  const long CL_FP_ROUND_TO_NEAREST = (1<<2);
+  const long CL_FP_ROUND_TO_ZERO = (1<<3);
+  const long CL_FP_ROUND_TO_INF = (1<<4);
+  const long CL_FP_FMA = (1<<5);
+  const long CL_FP_SOFT_FLOAT = (1<<6);
+  const long CL_NONE = 0x0;
+  const long CL_READ_ONLY_CACHE = 0x1;
+  const long CL_READ_WRITE_CACHE = 0x2;
+  const long CL_LOCAL = 0x1;
+  const long CL_GLOBAL = 0x2;
+  const long CL_EXEC_KERNEL = (1<<0);
+  const long CL_EXEC_NATIVE_KERNEL = (1<<1);
+  const long CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE = (1<<0);
+  const long CL_QUEUE_PROFILING_ENABLE = (1<<1);
+  const long CL_CONTEXT_REFERENCE_COUNT = 0x1080;
+  const long CL_CONTEXT_DEVICES = 0x1081;
+  const long CL_CONTEXT_PROPERTIES = 0x1082;
+  const long CL_CONTEXT_NUM_DEVICES = 0x1083;
+  const long CL_CONTEXT_PLATFORM = 0x1084;
+  const long CL_QUEUE_CONTEXT = 0x1090;
+  const long CL_QUEUE_DEVICE = 0x1091;
+  const long CL_QUEUE_REFERENCE_COUNT = 0x1092;
+  const long CL_QUEUE_PROPERTIES = 0x1093;
+  const long CL_MEM_READ_WRITE = (1<<0);
+  const long CL_MEM_WRITE_ONLY = (1<<1);
+  const long CL_MEM_READ_ONLY = (1<<2);
+  const long CL_MEM_USE_HOST_PTR = (1<<3);
+  const long CL_MEM_ALLOC_HOST_PTR = (1<<4);
+  const long CL_MEM_COPY_HOST_PTR = (1<<5);
+  const long CL_R = 0x10B0;
+  const long CL_A = 0x10B1;
+  const long CL_RG = 0x10B2;
+  const long CL_RA = 0x10B3;
+  const long CL_RGB = 0x10B4;
+  const long CL_RGBA = 0x10B5;
+  const long CL_BGRA = 0x10B6;
+  const long CL_ARGB = 0x10B7;
+  const long CL_INTENSITY = 0x10B8;
+  const long CL_LUMINANCE = 0x10B9;
+  const long CL_Rx = 0x10BA;
+  const long CL_RGx = 0x10BB;
+  const long CL_RGBx = 0x10BC;
+  const long CL_SNORM_INT8 = 0x10D0;
+  const long CL_SNORM_INT16 = 0x10D1;
+  const long CL_UNORM_INT8 = 0x10D2;
+  const long CL_UNORM_INT16 = 0x10D3;
+  const long CL_UNORM_SHORT_565 = 0x10D4;
+  const long CL_UNORM_SHORT_555 = 0x10D5;
+  const long CL_UNORM_INT_101010 = 0x10D6;
+  const long CL_SIGNED_INT8 = 0x10D7;
+  const long CL_SIGNED_INT16 = 0x10D8;
+  const long CL_SIGNED_INT32 = 0x10D9;
+  const long CL_UNSIGNED_INT8 = 0x10DA;
+  const long CL_UNSIGNED_INT16 = 0x10DB;
+  const long CL_UNSIGNED_INT32 = 0x10DC;
+  const long CL_HALF_FLOAT = 0x10DD;
+  const long CL_FLOAT = 0x10DE;
+  const long CL_MEM_OBJECT_BUFFER = 0x10F0;
+  const long CL_MEM_OBJECT_IMAGE2D = 0x10F1;
+  const long CL_MEM_OBJECT_IMAGE3D = 0x10F2;
+  const long CL_MEM_TYPE = 0x1100;
+  const long CL_MEM_FLAGS = 0x1101;
+  const long CL_MEM_SIZE = 0x1102;
+  const long CL_MEM_HOST_PTR = 0x1103;
+  const long CL_MEM_MAP_COUNT = 0x1104;
+  const long CL_MEM_REFERENCE_COUNT = 0x1105;
+  const long CL_MEM_CONTEXT = 0x1106;
+  const long CL_MEM_ASSOCIATED_MEMOBJECT = 0x1107;
+  const long CL_MEM_OFFSET = 0x1108;
+  const long CL_IMAGE_FORMAT = 0x1110;
+  const long CL_IMAGE_ELEMENT_SIZE = 0x1111;
+  const long CL_IMAGE_ROW_PITCH = 0x1112;
+  const long CL_IMAGE_SLICE_PITCH = 0x1113;
+  const long CL_IMAGE_WIDTH = 0x1114;
+  const long CL_IMAGE_HEIGHT = 0x1115;
+  const long CL_IMAGE_DEPTH = 0x1116;
+  const long CL_ADDRESS_NONE = 0x1130;
+  const long CL_ADDRESS_CLAMP_TO_EDGE = 0x1131;
+  const long CL_ADDRESS_CLAMP = 0x1132;
+  const long CL_ADDRESS_REPEAT = 0x1133;
+  const long CL_ADDRESS_MIRRORED_REPEAT = 0x1134;
+  const long CL_FILTER_NEAREST = 0x1140;
+  const long CL_FILTER_LINEAR = 0x1141;
+  const long CL_SAMPLER_REFERENCE_COUNT = 0x1150;
+  const long CL_SAMPLER_CONTEXT = 0x1151;
+  const long CL_SAMPLER_NORMALIZED_COORDS = 0x1152;
+  const long CL_SAMPLER_ADDRESSING_MODE = 0x1153;
+  const long CL_SAMPLER_FILTER_MODE = 0x1154;
+  const long CL_MAP_READ = (1<<0);
+  const long CL_MAP_WRITE = (1<<1);
+  const long CL_PROGRAM_REFERENCE_COUNT = 0x1160;
+  const long CL_PROGRAM_CONTEXT = 0x1161;
+  const long CL_PROGRAM_NUM_DEVICES = 0x1162;
+  const long CL_PROGRAM_DEVICES = 0x1163;
+  const long CL_PROGRAM_SOURCE = 0x1164;
+  const long CL_PROGRAM_BINARY_SIZES = 0x1165;
+  const long CL_PROGRAM_BINARIES = 0x1166;
+  const long CL_PROGRAM_BUILD_STATUS = 0x1181;
+  const long CL_PROGRAM_BUILD_OPTIONS = 0x1182;
+  const long CL_PROGRAM_BUILD_LOG = 0x1183;
+  const long CL_BUILD_SUCCESS = 0;
+  const long CL_BUILD_NONE = -1;
+  const long CL_BUILD_ERROR = -2;
+  const long CL_BUILD_IN_PROGRESS = -3;
+  const long CL_KERNEL_FUNCTION_NAME = 0x1190;
+  const long CL_KERNEL_NUM_ARGS = 0x1191;
+  const long CL_KERNEL_REFERENCE_COUNT = 0x1192;
+  const long CL_KERNEL_CONTEXT = 0x1193;
+  const long CL_KERNEL_PROGRAM = 0x1194;
+  const long CL_KERNEL_WORK_GROUP_SIZE = 0x11B0;
+  const long CL_KERNEL_COMPILE_WORK_GROUP_SIZE = 0x11B1;
+  const long CL_KERNEL_LOCAL_MEM_SIZE = 0x11B2;
+  const long CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE = 0x11B3;
+  const long CL_KERNEL_PRIVATE_MEM_SIZE = 0x11B4;
+  const long CL_EVENT_COMMAND_QUEUE = 0x11D0;
+  const long CL_EVENT_COMMAND_TYPE = 0x11D1;
+  const long CL_EVENT_REFERENCE_COUNT = 0x11D2;
+  const long CL_EVENT_COMMAND_EXECUTION_STATUS = 0x11D3;
+  const long CL_EVENT_CONTEXT = 0x11D4;
+  const long CL_COMMAND_NDRANGE_KERNEL = 0x11F0;
+  const long CL_COMMAND_TASK = 0x11F1;
+  const long CL_COMMAND_NATIVE_KERNEL = 0x11F2;
+  const long CL_COMMAND_READ_BUFFER = 0x11F3;
+  const long CL_COMMAND_WRITE_BUFFER = 0x11F4;
+  const long CL_COMMAND_COPY_BUFFER = 0x11F5;
+  const long CL_COMMAND_READ_IMAGE = 0x11F6;
+  const long CL_COMMAND_WRITE_IMAGE = 0x11F7;
+  const long CL_COMMAND_COPY_IMAGE = 0x11F8;
+  const long CL_COMMAND_COPY_IMAGE_TO_BUFFER = 0x11F9;
+  const long CL_COMMAND_COPY_BUFFER_TO_IMAGE = 0x11FA;
+  const long CL_COMMAND_MAP_BUFFER = 0x11FB;
+  const long CL_COMMAND_MAP_IMAGE = 0x11FC;
+  const long CL_COMMAND_UNMAP_MEM_OBJECT = 0x11FD;
+  const long CL_COMMAND_MARKER = 0x11FE;
+  const long CL_COMMAND_ACQUIRE_GL_OBJECTS = 0x11FF;
+  const long CL_COMMAND_RELEASE_GL_OBJECTS = 0x1200;
+  const long CL_COMMAND_READ_BUFFER_RECT = 0x1201;
+  const long CL_COMMAND_WRITE_BUFFER_RECT = 0x1202;
+  const long CL_COMMAND_COPY_BUFFER_RECT = 0x1203;
+  const long CL_COMMAND_USER = 0x1204;
+  const long CL_COMPLETE = 0x0;
+  const long CL_RUNNING = 0x1;
+  const long CL_SUBMITTED = 0x2;
+  const long CL_QUEUED = 0x3;
+  const long CL_BUFFER_CREATE_TYPE_REGION = 0x1220;
+  const long CL_PROFILING_COMMAND_QUEUED = 0x1280;
+  const long CL_PROFILING_COMMAND_SUBMIT = 0x1281;
+  const long CL_PROFILING_COMMAND_START = 0x1282;
+  const long CL_PROFILING_COMMAND_END = 0x1283;
+%{C++
+  */
+%}
+
+};
+
diff -r 450143d2d810 browser/components/webcl/public/IWebCLCommandQueue.idl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/IWebCLCommandQueue.idl	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,411 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \interface IWebCLCommandQueue
+ * IWebCLCommandQueue interface abstracts a WebCL command queue.
+ * \see cl_command_queue
+ */
+
+#include "nsISupports.idl"
+#include "nsISecurityCheckedComponent.idl"
+#include "nsIVariant.idl"
+
+#include "WebCL_types.idl"
+
+interface IWebCLEvent;
+interface IWebCLKernel;
+interface IWebCLMemoryObject;
+
+[scriptable, uuid(751b06c0-cac3-4123-87ae-2b8c22832d52)]
+interface IWebCLCommandQueue : nsISecurityCheckedComponent
+{
+  /** Get command queue info.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetCommandQueueInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getCommandQueueInfo (in long aName, [optional] in long aType);
+
+  /** Enqueues a command to execute a kernel on a device.
+   * \param aKernel A WebCLKernel instance.
+   * \param aWorkDim The number of dimensions used to specify the global
+   *  work-items and work-items in the work-group.
+   * \param aGlobalWorkOffset Array of aWorkDim integers that describe
+   *  the offset used to calculate the global ID of a work-item.
+   * \param aGlobalWorkSize Array of aWorkDim integers that describe
+   *  the number of global work-items in work_dim dimensions that
+   *  will execute the kernel function.
+   * \param aLocalWorkSize Array of aWorkDim integers that describe
+   *  the number of work-items that make up a work-group that will
+   *  execute the kernel specified by kernel.
+   * \param aEventWaitList Optional array of IWebCLEvents that need
+   *  to complete before this particular command can be executed.
+   * \return A WebCLEvent instance that identifies this particular
+   *  kernel execution instance
+   * \see clEnqueueNDRangeKernel
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueNDRangeKernel (in nsISupports aKernel,
+                                    in unsigned long aWorkDim,
+                                    in nsIVariant aGlobalWorkOffset,
+                                    in nsIVariant aGlobalWorkSize,
+                                    in nsIVariant aLocalWorkSize,
+                                    [optional] in nsIVariant aEventWaitList);
+
+  /** Enqueues a command to execute a kernel on a device.
+   * \param aKernel A WebCLKernel instance.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \return A WebCLEvent instance that identifies this particular
+   *  kernel execution instance
+   * \see clEnqueueTask
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueTask (in nsISupports aKernel,
+                           [optional] in nsIVariant aEventWaitList);
+
+  /** Enqueue commands to write to a buffer object from host memory.
+   * \param aBuffer A WebCLMemoryObject instance created as a buffer.
+   * \param aBlockingWrite Indicates if the write operations are
+   *  blocking or nonblocking.
+   * \param aOffset The offset in bytes in the buffer object to write to.
+   * \param aSize The size in bytes of data being written.
+   * \param aDataObject A WebCLDataObject instance from which the data is
+   *  to be written from. The buffer size must be at least \c aSize bytes.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \return A WebCLEvent instance that identifies this particular command.
+   * \see clEnqueueWriteBuffer
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueWriteBuffer (in nsISupports aBuffer,
+                                  in boolean aBlockingWrite,
+                                  in T_WebCLSize aOffset,
+                                  in T_WebCLSize aSize,
+                                  in nsIVariant aData,
+                                  [optional] in nsIVariant aEventWaitList);
+
+  /** Enqueue commands to read from a buffer object to host memory.
+   * \param aBuffer A WebCLMemoryObject instance created as a buffer.
+   * \param aBlockingRead Indicates if the read operations are
+   *  blocking or nonblocking.
+   * \param aOffset The offset in bytes in the buffer object to read from.
+   * \param aSize The size in bytes of data being read.
+   * \param aDataObject A WebCLDataObject instance to which the data is
+   *  to be read to. The buffer size must be at least \c aSize bytes.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \return A WebCLEvent instance that identifies this particular command.
+   * \see clEnqueueReadBuffer
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueReadBuffer (in nsISupports aBuffer,
+                                 in boolean aBlockingRead,
+                                 in T_WebCLSize aOffset,
+                                 in T_WebCLSize aSize,
+                                 in nsIVariant aData,
+                                 [optional] in nsIVariant aEventWaitList);
+
+  /** Enqueue commands to write a rectangular region to a buffer object
+   * from host memory.
+   * \param aBuffer A WebCLMemoryObject instance created as a buffer.
+   * \param aBlockingWrite Indicates if the write operations are
+   *  blocking or nonblocking.
+   * \param aBufferOrigin Array of 3 integers.
+   * \param aHostOrigin Array of 3 integers.
+   * \param aRegion Array of 3 integers.
+   * \param aBufferRowPitch
+   * \param aBufferSlicePitch
+   * \param aHostRowPitch
+   * \param aHostSlicePitch
+   * \param aDataObject A WebCLDataObject instance from which the data is
+   *  to be written from. A large enough buffer must be allocated.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \return A WebCLEvent instance that identifies this particular command.
+   * \see clEnqueueWriteBufferRect
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueWriteBufferRect (in nsISupports aBuffer,
+                                      in boolean aBlockingWrite,
+                                      in nsIVariant aBufferOrigin,
+                                      in nsIVariant aHostOrigin,
+                                      in nsIVariant aRegion,
+                                      in T_WebCLSize aBufferRowPitch,
+                                      in T_WebCLSize aBufferSlicePitch,
+                                      in T_WebCLSize aHostRowPitch,
+                                      in T_WebCLSize aHostSlicePitch,
+                                      in nsIVariant aData,
+                                      [optional] in nsIVariant aEventWaitList);
+
+  /** Enqueue commands to read from a rectangular region from a buffer
+   * object to host memory.
+   * \param aBuffer A WebCLMemoryObject instance created as a buffer.
+   * \param aBlockingRead Indicates if the read operations are
+   *  blocking or nonblocking.
+   * \param aBufferOrigin Array of 3 integers.
+   * \param aHostOrigin Array of 3 integers.
+   * \param aRegion Array of 3 integers.
+   * \param aBufferRowPitch
+   * \param aBufferSlicePitch
+   * \param aHostRowPitch
+   * \param aHostSlicePitch
+   * \param aDataObject A WebCLDataObject instance to which the data is
+   *  to be read to. A large enough buffer must be allocated.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \return A WebCLEvent instance that identifies this particular command.
+   * \see clEnqueueReadBufferRect
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueReadBufferRect (in nsISupports aBuffer,
+                                     in boolean aBlockingRead,
+                                     in nsIVariant aBufferOrigin,
+                                     in nsIVariant aHostOrigin,
+                                     in nsIVariant aRegion,
+                                     in T_WebCLSize aBufferRowPitch,
+                                     in T_WebCLSize aBufferSlicePitch,
+                                     in T_WebCLSize aHostRowPitch,
+                                     in T_WebCLSize aHostSlicePitch,
+                                     in nsIVariant aData,
+                                     [optional] in nsIVariant aEventWaitList);
+
+  /** Enqueues a command to write to a 2D or 3D image object from host memory.
+   * \param aImage A WebCLMemoryObject instance created as an image.
+   * \param aBlockingWrite Indicates if the write operations are
+   *  blocking or nonblocking.
+   * \param aOrigin Array of 3 integers.
+   * \param aRegion Array of 3 integers.
+   * \param aInputRowPitch
+   * \param aInputSlicePitch
+   * \param aDataObject A WebCLDataObject instance from which the data is
+   *  to be written from. A large enough buffer must be allocated.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \return A WebCLEvent instance that identifies this particular command.
+   * \see clEnqueueWriteImage
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueWriteImage (in nsISupports aImage,
+                                 in boolean aBlockingWrite,
+                                 in nsIVariant aOrigin,
+                                 in nsIVariant aRegion,
+                                 in T_WebCLSize aInputRowPitch,
+                                 in T_WebCLSize aInputSlicePitch,
+                                 in nsIVariant aData,
+                                 [optional] in nsIVariant aEventWaitList);
+
+  /** Enqueues a command to read from a 2D or 3D image object to host memory.
+   * \param aImage A WebCLMemoryObject instance created as an image.
+   * \param aBlockingRead Indicates if the read operations are
+   *  blocking or nonblocking.
+   * \param aOrigin Array of 3 integers.
+   * \param aRegion Array of 3 integers.
+   * \param aRowPitch
+   * \param aSlicePitch
+   * \param aDataObject A WebCLDataObject instance to which the data is
+   *  to be read to. A large enough buffer must be allocated.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \return A WebCLEvent instance that identifies this particular command.
+   * \see clEnqueueReadImage
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueReadImage (in nsISupports aImage,
+                                in boolean aBlockingRead,
+                                in nsIVariant aOrigin,
+                                in nsIVariant aRegion,
+                                in T_WebCLSize aRowPitch,
+                                in T_WebCLSize aSlicePitch,
+                                in nsIVariant aData,
+                                [optional] in nsIVariant aEventWaitList);
+
+  /** Enqueues a command to copy image objects.
+   * \param aSrcImage Source image, a WebCLMemoryObject instance created
+   *  as an image.
+   * \param aDstImage Destination image, a WebCLMemoryObject instance
+   *  created as an image.
+   * \param aSrcOrigin Array of 3 integers.
+   * \param aDstOrigin Array of 3 integers.
+   * \param aRegion Array of 3 integers.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \return A WebCLEvent instance that identifies this particular command.
+   * \see clEnqueueCopyImage
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueCopyImage (in nsISupports aSrcImage,
+                                in nsISupports aDstImage,
+                                in nsIVariant aSrcOrigin,
+                                in nsIVariant aDstOrigin,
+                                in nsIVariant aRegion,
+                                [optional] in nsIVariant aEventWaitList);
+
+  /** Enqueues a command to copy an image object to a buffer object.
+   * \param aSrcImage Source image, a WebCLMemoryObject instance created
+   *  as an image.
+   * \param aDstBuffer Destination buffer, a WebCLMemoryObject instance
+   *  created as a buffer.
+   * \param aSrcOrigin Array of 3 integers.
+   * \param aRegion Array of 3 integers.
+   * \param aDstOffset The offset where to begin copying data into aDstBuffer.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \return A WebCLEvent instance that identifies this particular command.
+   * \see clEnqueueCopyImageToBuffer
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueCopyImageToBuffer (in nsISupports aSrcImage,
+                                        in nsISupports aDstBuffer,
+                                        in nsIVariant aSrcOrigin,
+                                        in nsIVariant aRegion,
+                                        in T_WebCLSize aDstOffset,
+                                        [optional] in nsIVariant aEventWaitList);
+
+  /** Enqueues a command to copy a buffer object to an image object.
+   * \param aSrcBuffer Source buffer, a WebCLMemoryObject instance
+   *  created as a buffer.
+   * \param aDstImage Destination image, a WebCLMemoryObject
+   *  instance created as an image.
+   * \param aSrcOffset The offset where to begin copying data from aSrcBuffer.
+   * \param aDstOrigin Array of 3 integers.
+   * \param aRegion Array of 3 integers.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \return A WebCLEvent instance that identifies this particular command.
+   * \see clEnqueueCopyBufferToImage
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueCopyBufferToImage (in nsISupports aSrcBuffer,
+                                        in nsISupports aDstImage,
+                                        in T_WebCLSize aSrcOffset,
+                                        in nsIVariant aDstOrigin,
+                                        in nsIVariant aRegion,
+                                        [optional] in nsIVariant aEventWaitList);
+
+  /** Enqueues a command to map a region of the buffer object given by aBuffer
+   * into the host address space represented by aDataObject.
+   * \param aBuffer A WebCLMemoryObject instance created as a buffer.
+   * \param aBlockingMap Indicates if the map operation is blocking
+   *  or non-blocking.
+   * \param aMapFlags A bit field of valid mapping flags (CL_MAP_READ,
+   *  CL_MAP_WRITE).
+   * \param aOffset The offset in bytes of the region in the buffer
+   *  object that is being mapped.
+   * \param aSize The size in bytes of the region in the buffer
+   *  object that is being mapped.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \param aDataObject The data object into which the buffer is to be mapped.
+   * \return A WebCLEvent instance that identifies this particular command.
+   * \see clEnqueueMapBuffer
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueMapBuffer (in nsISupports aBuffer,
+                                in boolean aBlockingMap,
+                                in T_WebCLMapFlags aMapFlags,
+                                in T_WebCLSize aOffset,
+                                in T_WebCLSize aSize,
+                                in nsIVariant aEventWaitList,
+                                in nsIVariant aData);
+
+  /** Enqueues a command to map a region of an image object given by aImage
+   * into the host address space represented by aDataObject.
+   * \param aImage A WebCLMemoryObject instance created as an image.
+   * \param aBlockingMap Indicates if the map operation is blocking
+   *  or non-blocking.
+   * \param aMapFlags A bit field of valid mapping flags (CL_MAP_READ,
+   *  CL_MAP_WRITE).
+   * \param aOrigin The offset (x, y, z) in pixels of the 2D or 3D
+   *  rectangle region that is to be mapped. Array of 3 integers.
+   * \param aRegion The region (width, height, depth) in pixels of
+   *  the 2D or 3D rectangle region that is to be mapped.
+   *  Array of 3 integers.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \return A WebCLEvent instance that identifies this particular command.
+   * \param aDataObject The data object into which the image is to be mapped.
+   * \see clEnqueueMapImage
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueMapImage (in nsISupports aImage,
+                               in boolean aBlockingMap,
+                               in T_WebCLMapFlags aMapFlags,
+                               in nsIVariant aOrigin,
+                               in nsIVariant aRegion,
+                               in nsIVariant aEventWaitList,
+                               in nsIVariant aData);
+
+  /** Enqueues a command to unmap a previously mapped region of
+   * a memory object.
+   * \param aMemObject A WebCLMemoryObject instance.
+   * \param aMappedDataObject A WebCLDataObject instance returned by a previous
+   *  call to enqueueMapBuffer or enqueueMapImage.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \return A WebCLEvent instance that identifies this particular command.
+   * \see clEnqueueUnmapMemObject
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueUnmapMemObject (in nsISupports aMemObject,
+                                     in nsIVariant aMappedData,
+                                     [optional] in nsIVariant aEventWaitList);
+
+  /** Enqueues a marker command.
+   * \return A WebCLEvent instance that identifies the enqueued marker.
+   * \see clEnqueueMarker
+   */
+  [implicit_jscontext]
+  IWebCLEvent enqueueMarker ();
+
+  /** Enqueues a command to wait for a specific event or a list of events
+   * to complete before any future commands queued in the command-queue
+   * are executed.
+   * \param aEventWaitList Optional array of IWebCLEvents.
+   * \see clEnqueueWaitForEvents
+   */
+  [implicit_jscontext]
+  void enqueueWaitForEvents (in nsIVariant aEventWaitList);
+
+  /** A synchronization point that enqueues a barrier operation.
+   * \see clEnqueueBarrier
+   */
+  [implicit_jscontext]
+  void enqueueBarrier ();
+
+  /** Issues all previously queued commands in a command queue to the
+   * device associated with the command-queue.
+   * \see clFlush
+   */
+  [implicit_jscontext]
+  void flush ();
+
+  /** Blocks until all previously queued commands in a command queue are
+   * issued to the associated device and have completed.
+   * \see clFinish
+   */
+  [implicit_jscontext]
+  void finish ();
+
+  /** Immediately releases all OpenCL-related resources if any are allocated
+   * for this object. The object should not be used anymore after calling
+   * this function.
+   */
+  void releaseCLResources ();
+};
diff -r 450143d2d810 browser/components/webcl/public/IWebCLContext.idl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/IWebCLContext.idl	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,181 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \interface IWebCLContext
+ * IWebCLContext interface abstracts a WebCL context.
+ * \see cl_context
+ */
+
+#include "nsISupports.idl"
+#include "nsISecurityCheckedComponent.idl"
+#include "nsIVariant.idl"
+
+#include "nsIDOMWebGLRenderingContext.idl"
+
+#include "WebCL_types.idl"
+
+interface IWebCLProgram;
+interface IWebCLCommandQueue;
+interface IWebCLDevice;
+interface IWebCLMemoryObject;
+interface IWebCLImageFormat;
+interface IWebCLSampler;
+interface IWebCLEvent;
+
+[scriptable, uuid(0e5fba5c-091f-40db-a6a9-700ba50393d0)]
+interface IWebCLContext : nsISecurityCheckedComponent
+{
+  /** Get context info.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetContextInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getContextInfo (in long aName, [optional] in long aType);
+
+  /** Creates a program object for a context, and loads the source code
+   * specified by the text string aSource into the program object.
+   * \param aSource The program source code.
+   * \return A WebCLProgram instance.
+   * \see clCreateProgramWithSource
+   */
+  [implicit_jscontext]
+  IWebCLProgram createProgramWithSource (in string aSource);
+
+  /** Create a command-queue on a specific device.
+   * \param aDevice A WebCLDevice instance associated with the context.
+   * \param aProperties Specifies a list of properties for the command queue.
+   * \return A WebCLCommandQueue instance.
+   * \see clCreateCommandQueue
+   */
+  [implicit_jscontext]
+  IWebCLCommandQueue createCommandQueue (in nsISupports aDevice,
+                                         in T_WebCLCommandQueueProperties aProperties);
+
+  /** Creates a buffer object.
+   * \param aFlags A bit-field that is used to specify allocation
+   *  and usage information
+   * \param aSize The size in bytes of the buffer memory object
+   *  to be allocated.
+   * \return A WebCLMemoryObject instance representing a buffer.
+   * \see clCreateBuffer
+   */
+  [implicit_jscontext]
+  IWebCLMemoryObject createBuffer (in T_WebCLMemFlags aFlags,
+                                   in T_WebCLSize aSize);
+
+  /** Creates a 2D image object.
+   * \param aFlags A bit-field that is used to specify allocation
+   * \param aImageFormat An object with "channelOrder" and "channelDataType"
+   *                     properties of integer type. (Also "image_channel_order"
+   *                     and "image_channel_data_type" are accepted but not
+   *                     recommended for use.)
+   * \param aWidth The width of the image in pixels.
+   * \param aHeight The height of the image in pixels.
+   * \param aRowPitch The scan-line pitch in bytes.
+   * \return WebCLMemoryObject instance  representing a 2D image.
+   * \see clCreateImage2D
+   * \see getSupportedImageFormats
+   */
+  [implicit_jscontext]
+  IWebCLMemoryObject createImage2D (in T_WebCLMemFlags aFlags,
+                                    in nsIVariant aImageFormat,
+                                    in T_WebCLSize aWidth,
+                                    in T_WebCLSize aHeight,
+                                    in T_WebCLSize aRowPitch);
+
+  /** Creates a 3D image object.
+   * \param aFlags A bit-field that is used to specify allocation
+   * \param aImageFormat An object with "channelOrder" and "channelDataType"
+   *                     properties of integer type. (Also "image_channel_order"
+   *                     and "image_channel_data_type" are accepted but not
+   *                     recommended for use.)
+   * \param aWidth The width of the image in pixels.
+   * \param aHeight The height of the image in pixels.
+   * \param aDepth The depth of the image in pixels.
+   * \param aRowPitch The scan-line pitch in bytes.
+   * \param aSlicePitch The size in bytes of each 2D slice in the 3D image.
+   * \return WebCLMemoryObject instance representing a 3D image.
+   * \see clCreateImage3D
+   * \see getSupportedImageFormats
+   */
+  [implicit_jscontext]
+  IWebCLMemoryObject createImage3D (in T_WebCLMemFlags aFlags,
+                                    in nsIVariant aImageFormat,
+                                    in T_WebCLSize aWidth,
+                                    in T_WebCLSize aHeight,
+                                    in T_WebCLSize aDepth,
+                                    in T_WebCLSize aRowPitch,
+                                    in T_WebCLSize aSlicePitch);
+
+  /** Creates a sampler object.
+   * \param aNormalizedCoords Determines if the image coordinates specified
+   * are normalized (true) or not (false).
+   * \param aAddressingMode Specifies how out-of-range image coordinates are
+   *  handled when reading from an image.
+   * \param aFilterMode Specifies the type of filter that must be applied when
+   *  reading an image.
+   * \return WebCLMemoryObject instance representing a sampler.
+   * \see clCreateSampler
+   */
+  [implicit_jscontext]
+  IWebCLSampler createSampler (in boolean aNormalizedCoords,
+                               in T_WebCLAddressingMode aAddressingMode,
+                               in T_WebCLFilterMode aFilterMode);
+
+  /** Get the list of image formats supported by an OpenCL implementation.
+   * \param aFlags A bit-field that is used to specify allocation
+   * \param aImageType Describes the image type and must be either
+   *  CL_MEM_OBJECT_IMAGE2D or CL_MEM_OBJECT_IMAGE3D.
+   * \return A JSArray of image formats wrapped in an nsIVariant. Each image
+   *  format item is an object with properties channelOrder and
+   *  channelDataType.
+   * \see clGetSupportedImageFormats
+   */
+  [implicit_jscontext]
+  nsIVariant getSupportedImageFormats (in T_WebCLMemFlags aFlags,
+                                       in T_WebCLMemObjectType aImageType);
+
+  /** Creates a user event object.
+   * User events allow applications to enqueue commands that wait on
+   * a user event to finish before the command is executed by the device.
+   * \return A WebCLEvent instance.
+   * \see clCreateUserEvent
+   */
+  [implicit_jscontext]
+  IWebCLEvent createUserEvent ();
+
+  /** Immediately releases all OpenCL-related resources if any are allocated
+   * for this object. The object should not be used anymore after calling
+   * this function.
+   */
+  void releaseCLResources ();
+};
diff -r 450143d2d810 browser/components/webcl/public/IWebCLDevice.idl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/IWebCLDevice.idl	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,53 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \interface IWebCLDevice
+ * IWebCLDevice interface abstracts a WebCL device.
+ * \see cl_device_id
+ */
+
+#include "nsISupports.idl"
+#include "nsISecurityCheckedComponent.idl"
+#include "nsIVariant.idl"
+
+#include "WebCL_types.idl"
+
+[scriptable, uuid(f5352722-9a35-405b-95ae-54d5b4995576)]
+interface IWebCLDevice : nsISecurityCheckedComponent
+{
+  /** Get device info.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetDeviceInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getDeviceInfo (in long aName, [optional] in long aType);
+};
diff -r 450143d2d810 browser/components/webcl/public/IWebCLEvent.idl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/IWebCLEvent.idl	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,80 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \interface IWebCLEvent
+ * IWebCLEvent interface abstracts a WebCL event.
+ * \see cl_event
+ */
+
+#include "nsISupports.idl"
+#include "nsISecurityCheckedComponent.idl"
+#include "nsIVariant.idl"
+
+#include "WebCL_types.idl"
+
+[scriptable, uuid(cf7372e6-f2ec-467d-99dc-9eeb756bc3e3)]
+interface IWebCLEvent : nsISecurityCheckedComponent
+{
+  /** Get event info.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetEventInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getEventInfo (in long aName, [optional] in long aType);
+
+  /** Get event profiling info.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetEventProfilingInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getEventProfilingInfo (in long aName, [optional] in long aType);
+
+  /** Sets the execution status of a user event object.
+   * \param aExecutionStatus Specifies the new execution status to be set
+   *  and can be CL_COMPLETE or a negative integer value to indicate
+   *  an error. A negative integer value causes all enqueued commands that
+   *  wait on this user event to be terminated. clSetUserEventStatus can
+   *  only be called once to change the execution status of event.
+   * \see clSetUserEventStatus
+   */
+  [implicit_jscontext]
+  void setUserEventStatus (in long aExecutionStatus);
+
+  /** Immediately releases all OpenCL-related resources if any are allocated
+   * for this object. The object should not be used anymore after calling
+   * this function.
+   */
+  void releaseCLResources ();
+};
diff -r 450143d2d810 browser/components/webcl/public/IWebCLKernel.idl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/IWebCLKernel.idl	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,95 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \interface IWebCLKernel
+ * IWebCLKernel interface abstracts a WebCL kernel.
+ * \see cl_kernel
+ */
+
+#include "nsISupports.idl"
+#include "nsISecurityCheckedComponent.idl"
+#include "nsIVariant.idl"
+
+#include "WebCL_types.idl"
+
+interface IWebCLDevice;
+
+[scriptable, uuid(5d1be1d7-aad2-4eb3-918b-e9551079d634)]
+interface IWebCLKernel : nsISecurityCheckedComponent
+{
+  /** Get kernel info.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetKernelInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getKernelInfo (in long aName, [optional] in long aType);
+
+  /** Get kernel work group info.
+   * \param aDevice A WebCLDevice instance.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetKernelWorkGroupInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getKernelWorkGroupInfo (in nsISupports aDevice, in long aName, [optional] in long aType);
+
+  /** Set the argument value for a specific argument of a kernel.
+   * \param aIndex The argument index.
+   * \param aValue Value to be set.
+   * \param aType Type of the value to be set (one of WebCL.types)
+   * \see clSetKernelArg
+   * \see WebCL_types
+   */
+  // TODO: Might be a good idea to support null, e.g. for cl_mems. (impl. as optional)
+  [implicit_jscontext]
+  void setKernelArg (in long aIndex,
+                     in nsIVariant aValue,
+                     [optional] in long aType);
+
+  /** Set local kernel argument.
+   * \param aIndex The argument index.
+   * \param aSize Size of the local argument.
+   * \see clSetKernelArg
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  void setKernelArgLocal (in long aIndex,
+                          in unsigned long aSize);
+
+  /** Immediately releases all OpenCL-related resources if any are allocated
+   * for this object. The object should not be used anymore after calling
+   * this function.
+   */
+  void releaseCLResources ();
+};
diff -r 450143d2d810 browser/components/webcl/public/IWebCLMemoryObject.idl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/IWebCLMemoryObject.idl	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,81 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \interface IWebCLMemoryObject
+ * IWebCLMemoryObject interface abstracts a WebCL memory object such as
+ * a buffer or an image.
+ * \see cl_mem
+ */
+
+#include "nsISupports.idl"
+#include "nsISecurityCheckedComponent.idl"
+#include "nsIVariant.idl"
+
+#include "WebCL_types.idl"
+
+[scriptable, uuid(e677e482-49e5-40de-ba4f-0e71f301286b)]
+interface IWebCLMemoryObject : nsISecurityCheckedComponent
+{
+  /** Get memory object info.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetMemObjectInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getMemObjectInfo (in long aName, [optional] in long aType);
+
+  /** Get image info.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetImageInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getImageInfo (in long aName, [optional] in long aType);
+
+  /** Creates a buffer object (referred to as a sub-buffer object) from
+   * an existing buffer object.
+   * \param aFlags A bit-field that is used to specify allocation and
+   *  usage information about the image memory object being created.
+   * \param aBufferRegion An object with "size" and "origin" properties of integer type.
+   * \see clCreateSubBuffer
+   */
+  [implicit_jscontext]
+  IWebCLMemoryObject createSubBuffer (in T_WebCLMemFlags aFlags,
+                                      in nsIVariant aBufferRegion);
+
+  /** Immediately releases all OpenCL-related resources if any are allocated
+   * for this object. The object should not be used anymore after calling
+   * this function.
+   */
+  void releaseCLResources ();
+};
diff -r 450143d2d810 browser/components/webcl/public/IWebCLPlatform.idl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/IWebCLPlatform.idl	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,64 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \interface IWebCLPlatform
+ * IWebCLPlatform interface abstracts a WebCL platform.
+ * \see cl_platform_id
+ */
+
+#include "nsISupports.idl"
+#include "nsISecurityCheckedComponent.idl"
+#include "nsIVariant.idl"
+
+#include "WebCL_types.idl"
+
+[scriptable, uuid(6ab8b8cf-4d87-40a0-af8a-cc0bf5251fa3)]
+interface IWebCLPlatform : nsISecurityCheckedComponent
+{
+  /** Get platform info.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetPlatformInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getPlatformInfo (in long aName, [optional] in long aType);
+
+  /** Obtain the list of devices available on a platform.
+   * \param aType A bitfield that identifies the type of OpenCL device.
+   * \return Array of IWebCLDevice instances.
+   * \see clGetDeviceIDs
+   */
+  [implicit_jscontext]
+  nsIVariant getDeviceIDs (in T_WebCLDeviceType aType);
+
+  [implicit_jscontext]
+  nsIVariant getDevices (in T_WebCLDeviceType aType);
+};
diff -r 450143d2d810 browser/components/webcl/public/IWebCLProgram.idl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/IWebCLProgram.idl	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,101 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \interface IWebCLProgram
+ * IWebCLProgram interface abstracts a WebCL program.
+ * \see cl_program
+ */
+
+#include "nsISupports.idl"
+#include "nsISecurityCheckedComponent.idl"
+#include "nsIVariant.idl"
+
+#include "WebCL_types.idl"
+
+interface IWebCLDevice;
+interface IWebCLKernel;
+
+[scriptable, uuid(74d49a1e-31e0-41d5-8e98-8980a077fcb2)]
+interface IWebCLProgram : nsISecurityCheckedComponent
+{
+  /** Get program info.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetProgramInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getProgramInfo (in long aName, [optional] in long aType);
+
+  /** Get program build info.
+   * \param aDevice A WebCLDevice instance for which build information is
+   *  being queried. Must be a valid device associated with the program instance.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetProgramBuildInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getProgramBuildInfo (in nsISupports aDevice, in long aName, [optional] in long aType);
+
+  /** Builds (compiles and links) a program executable from the program
+   * source or binary.
+   * \param aDevices Array of IWebCLDevice instances.
+   * \param aOptions A string that describes the build options to be
+   *  used for building the program executable.
+   * \see clBuildProgram
+   */
+  [implicit_jscontext]
+  void buildProgram (in nsIVariant aDevices,
+                     in string aOptions);
+
+  /** Creates a kernel object.
+   * \param aKernelName A function name in the program declared with
+   *  the __kernel qualifier.
+   * \return A WebCLKernel instance.
+   * \see clCreateKernel
+   */
+  [implicit_jscontext]
+  IWebCLKernel createKernel (in string aKernelName);
+
+  /** Creates kernel objects for all kernel functions in a program object.
+   * \return Array of IWebCLKernel instances.
+   * \see clCreateKernelsInProgram
+   */
+  [implicit_jscontext]
+  nsIVariant createKernelsInProgram ();
+
+  /** Immediately releases all OpenCL-related resources if any are allocated
+   * for this object. The object should not be used anymore after calling
+   * this function.
+   */
+  void releaseCLResources ();
+};
diff -r 450143d2d810 browser/components/webcl/public/IWebCLSampler.idl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/IWebCLSampler.idl	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,59 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \interface IWebCLSampler
+ * IWebCLSampler interface abstracts a WebCL sampler.
+ * \see cl_sampler
+ */
+
+#include "nsISupports.idl"
+#include "nsISecurityCheckedComponent.idl"
+#include "nsIVariant.idl"
+
+#include "WebCL_types.idl"
+
+[scriptable, uuid(dc9b25aa-2bdc-4efd-b295-b450c75d252c)]
+interface IWebCLSampler : nsISecurityCheckedComponent
+{
+  /** Get sampler info.
+   * \param aName Name of the info parameter.
+   * \param aType Optional type for the value (one of WebCL.types).
+   * \return The resulting value.
+   * \see clGetSamplerInfo
+   * \see WebCL_types
+   */
+  [implicit_jscontext]
+  nsIVariant getSamplerInfo (in long aName, [optional] in long aType);
+
+  /** Immediately releases all OpenCL-related resources if any are allocated
+   * for this object. The object should not be used anymore after calling
+   * this function.
+   */
+  void releaseCLResources ();
+};
diff -r 450143d2d810 browser/components/webcl/public/Makefile.in
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/Makefile.in	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,15 @@
+DEPTH   = ../../../..
+topsrcdir = @top_srcdir@
+srcdir    = @srcdir@
+VPATH   = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = webcl
+XPIDL_MODULE = webcl
+
+XPIDLSRCS = IWebCL.idl IWebCLPlatform.idl IWebCLDevice.idl IWebCLContext.idl \
+ IWebCLMemoryObject.idl IWebCLCommandQueue.idl IWebCLEvent.idl IWebCLProgram.idl \
+ IWebCLKernel.idl IWebCLSampler.idl WebCL.idl WebCL_types.idl
+
+include $(topsrcdir)/config/rules.mk
diff -r 450143d2d810 browser/components/webcl/public/WebCL.idl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/WebCL.idl	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,51 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/**
+ * WebCL IDLs.
+ * Other XPCOM components can use this file can be used for including all
+ * WebCL IDL files and their dependencies at the same time.
+ */
+
+#include "nsISupports.idl"
+#include "nsISecurityCheckedComponent.idl"
+#include "nsIVariant.idl"
+
+#include "WebCL_types.idl"
+
+#include "IWebCL.idl"
+#include "IWebCLPlatform.idl"
+#include "IWebCLContext.idl"
+#include "IWebCLDevice.idl"
+#include "IWebCLMemoryObject.idl"
+#include "IWebCLCommandQueue.idl"
+#include "IWebCLEvent.idl"
+#include "IWebCLProgram.idl"
+#include "IWebCLKernel.idl"
+#include "IWebCLSampler.idl"
diff -r 450143d2d810 browser/components/webcl/public/WebCL_types.idl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/public/WebCL_types.idl	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,71 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/**
+ * WebCL types.
+ * The types listed in this file are used on WebCL interface definitions.
+ */
+
+//typedef unsigned long           T_WebCLBitField;
+typedef unsigned long           T_WebCLSize;
+
+// Enumerated types
+typedef long                    T_WebCLEnum;
+typedef T_WebCLEnum             T_WebCLAddressingMode;
+typedef T_WebCLEnum             T_WebCLBufferCreateType;
+typedef T_WebCLEnum             T_WebCLBuildStatus;
+typedef T_WebCLEnum             T_WebCLChannelOrder;
+typedef T_WebCLEnum             T_WebCLChannelType;
+typedef T_WebCLEnum             T_WebCLCommandQueueInfo;
+typedef T_WebCLEnum             T_WebCLCommandQueueProperties;
+typedef T_WebCLEnum             T_WebCLCommandType;
+typedef T_WebCLEnum             T_WebCLContextInfo;
+typedef T_WebCLEnum             T_WebCLContextProperties;
+typedef T_WebCLEnum             T_WebCLDeviceExecCapabilities;
+typedef T_WebCLEnum             T_WebCLDeviceFPConfig;
+typedef T_WebCLEnum             T_WebCLDeviceInfo;
+typedef T_WebCLEnum             T_WebCLDeviceLocalMemType;
+typedef T_WebCLEnum             T_WebCLDeviceMemCacheType;
+typedef T_WebCLEnum             T_WebCLDeviceType;
+typedef T_WebCLEnum             T_WebCLEventInfo;
+typedef T_WebCLEnum             T_WebCLFilterMode;
+typedef T_WebCLEnum             T_WebCLGLObjectType;
+typedef T_WebCLEnum             T_WebCLGLTextureInfo;
+typedef T_WebCLEnum             T_WebCLImageInfo;
+typedef T_WebCLEnum             T_WebCLKernelInfo;
+typedef T_WebCLEnum             T_WebCLKernelWorkGroupInfo;
+typedef T_WebCLEnum             T_WebCLMapFlags;
+typedef T_WebCLEnum             T_WebCLFenceFlags;
+typedef T_WebCLEnum             T_WebCLMemFlags;
+typedef T_WebCLEnum             T_WebCLMemInfo;
+typedef T_WebCLEnum             T_WebCLMemObjectType;
+typedef T_WebCLEnum             T_WebCLPlatformInfo;
+typedef T_WebCLEnum             T_WebCLProfilingInfo;
+typedef T_WebCLEnum             T_WebCLProgramBuildInfo;
+typedef T_WebCLEnum             T_WebCLSamplerInfo;
diff -r 450143d2d810 browser/components/webcl/src/Makefile.in
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/Makefile.in	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,37 @@
+DEPTH		= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = webcl
+LIBRARY_NAME = webcl_s
+FORCE_STATIC_LIB = 1
+ifndef MOZ_MEMORY
+USE_STATIC_LIBS = 1
+endif
+
+DEFINES += \
+	-DMOZ_APP_NAME=$(MOZ_APP_NAME) \
+	-DMOZ_MACBUNDLE_NAME=$(MOZ_MACBUNDLE_NAME) \
+	-DWEBCL_VERSION_MAJOR=1 -DWEBCL_VERSION_MINOR=0 \
+	-DWEBCL_VERSION_RELEASE=3 -DWEBCL_VERSION_REV=0 \
+	$(NULL)
+
+ # LOG_LEVEL_NONE      0
+ # LOG_LEVEL_ERROR     1
+ # LOG_LEVEL_WARNING   2
+ # LOG_LEVEL_INFO      3
+ # LOG_LEVEL_DEBUG     4
+#DEFINES += -DWEBCL_ENABLE_LOG -DWEBCL_LOG_LEVEL_DEFAULT=3
+#DEFINES += -DWEBCL_TRACE_FUNCTIONS
+
+CPPSRCS = WebCL.cpp WebCLCommandQueue.cpp WebCLCommon.cpp WebCLContext.cpp \
+ WebCLDevice.cpp WebCLEvent.cpp WebCLKernel.cpp WebCLLogger.cpp \
+ WebCLMemoryObject.cpp WebCLObserver.cpp WebCLPlatform.cpp WebCLProgram.cpp \
+ WebCLSampler.cpp WebCL_clwrapper.cpp WebCL_internal.cpp WebCL_libcl.cpp
+
+LOCAL_INCLUDES = -I$(srcdir)/../../build
+
+include $(topsrcdir)/config/rules.mk
diff -r 450143d2d810 browser/components/webcl/src/WebCL.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCL.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,925 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \file WebCL.cpp
+ * WebCL component implementation.
+ */
+#include "WebCLCommon.h"
+
+#include "WebCL.h"
+
+#include "WebCL_internal.h"
+#include "WebCL_clwrapper.h"
+
+#include "WebCLPlatform.h"
+#include "WebCLContext.h"
+#include "WebCLDevice.h"
+#include "WebCLEvent.h"
+
+#include "WebCLObserver.h"
+
+#include "nsXPCOM.h"
+#include "nsCOMPtr.h"
+#include "nsError.h"
+#include "nsCRT.h"
+#include "jsapi.h"
+#include "nsISupportsPrimitives.h"
+#include "nsIClassInfoImpl.h"
+
+#include "nsComponentManagerUtils.h"
+
+#include "nsIVariant.h"
+
+#include "nsIJSRuntimeService.h"
+#include "nsIJSContextStack.h"
+#include "nsIXPConnect.h"
+#include "nsServiceManagerUtils.h"
+
+#include "nsStringAPI.h"
+
+// For prompter
+#include "nsIPrompt.h"
+#include "nsIWindowWatcher.h"
+#include "nsIPrefBranch2.h"
+#include "nsIPrefService.h"
+
+
+#define WEBCL_PREF_ID__OCLLIB "extensions.webcl.opencllib"
+#define WEBCL_PREF_ID__ALLOWED "extensions.webcl.allowed"
+#define WEBCL_PREF_VALUE__ALLOWED__NOT_SET -1
+#define WEBCL_PREF_VALUE__ALLOWED__FALSE 0
+#define WEBCL_PREF_VALUE__ALLOWED__TRUE 1
+
+
+#define WEBCL_ENSURE_USE_PERMITTED do{ \
+  if(!mWebCLUsePermitted) { \
+    if (mWebCLSecurityDialogNeeded) showSecurityPrompt (); \
+    if (!mWebCLUsePermitted) { \
+      D_LOG (LOG_LEVEL_ERROR, "WebCL use not permitted by user."); \
+      return NS_ERROR_NOT_AVAILABLE; \
+    } \
+  } }while(0)
+
+
+#define WEBCL_ENSURE_LIB_LOADED() do{ \
+  if (mLibLoadFailed) { \
+    WebCL_reportJSError (cx, "Failed to load OpenCL library."); \
+    return WEBCL_XPCOM_ERROR; \
+  } \
+  if (!mWrapper) { \
+    nsresult rv = loadLibrary (cx); \
+    NS_ENSURE_SUCCESS (rv, rv); \
+    NS_ENSURE_TRUE (mWrapper, NS_ERROR_NULL_POINTER); \
+  } }while(0)
+
+
+/* NOTE: We use the ClassInfo variant of NS_IMPL_ISUPPORTS to enable
+ * the nice ClassInfo-provided features such as interface flattening,
+ * i.e. no need to QI the global WebCL to Components.interfaces.IWebCL in JS.
+ */
+NS_IMPL_CLASSINFO (WebCL, NULL, 0, WEBCL_CID)
+NS_IMPL_ISUPPORTS2_CI(WebCL, IWebCL, nsISecurityCheckedComponent)
+
+
+WebCL::WebCL()
+  : IWebCL (),
+    WebCLCommon (),
+    mTypes (),
+    mWebCLUsePermitted (false),
+    mWebCLSecurityDialogNeeded (true),
+    mLibLoadFailed(false),
+    mObserver(new (std::nothrow) WebCLObserver)
+{
+  D_METHOD_START;
+
+  nsresult rv;
+
+  if (!mObserver)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to create WebCL observer.");
+    // TODO: report error to user
+    return;
+  }
+
+  mObserver->setWebCL (this);
+
+  // NOTE: Firefox 13 deprecates nsIPrefBranch2 in favor of nsIPrefBranch
+
+  //extensions.webcl.allowed
+  nsCOMPtr<nsIPrefBranch2> branch = do_GetService (NS_PREFSERVICE_CONTRACTID, &rv);
+  if (NS_SUCCEEDED (rv))
+  {
+
+    PRInt32 val = WEBCL_PREF_VALUE__ALLOWED__NOT_SET;
+    rv = branch->GetIntPref(WEBCL_PREF_ID__ALLOWED, &val);
+    if (NS_SUCCEEDED (rv))
+    {
+      D_LOG (LOG_LEVEL_DEBUG, "%s: %d",WEBCL_PREF_ID__ALLOWED, val);
+      if (val == WEBCL_PREF_VALUE__ALLOWED__NOT_SET)
+      {
+        mWebCLSecurityDialogNeeded = true;
+      }
+      else if (val == WEBCL_PREF_VALUE__ALLOWED__FALSE || val == WEBCL_PREF_VALUE__ALLOWED__TRUE)
+      {
+        mWebCLUsePermitted = (bool)val;
+        mWebCLSecurityDialogNeeded = false;
+      }
+      else
+      {
+        D_LOG (LOG_LEVEL_ERROR, "Unexpected value for preferense "
+               WEBCL_PREF_ID__ALLOWED ". Resetting to %d.", WEBCL_PREF_VALUE__ALLOWED__NOT_SET);
+        rv = branch->SetIntPref(WEBCL_PREF_ID__ALLOWED, WEBCL_PREF_VALUE__ALLOWED__NOT_SET);
+      }
+    }
+    else
+    {
+      rv = branch->SetIntPref(WEBCL_PREF_ID__ALLOWED, WEBCL_PREF_VALUE__ALLOWED__NOT_SET);
+      D_LOG (LOG_LEVEL_DEBUG, "%s: %d  (created as default)",WEBCL_PREF_ID__ALLOWED, val);
+    }
+
+    rv = branch->AddObserver(WEBCL_PREF_ID__ALLOWED, mObserver, PR_FALSE);
+    if (NS_SUCCEEDED (rv))
+      branch->AddObserver(WEBCL_PREF_ID__OCLLIB, mObserver, PR_FALSE);
+
+    if (NS_FAILED(rv))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to add preference observer, rv=%X.", rv);
+    }
+    else
+    {
+      D_LOG (LOG_LEVEL_DEBUG, "Preference observer registered.");
+    }
+  }
+  else
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to get preference service.");
+  }
+}
+
+
+WebCL::~WebCL()
+{
+  D_METHOD_START;
+
+  nsresult rv;
+  nsCOMPtr<nsIPrefBranch2> branch = do_GetService (NS_PREFSERVICE_CONTRACTID, &rv);
+  if (NS_SUCCEEDED (rv))
+  {
+    // TODO: Is this OK or should we store the original nsIPrefBranch2 instance from constructor?
+    rv = branch->RemoveObserver(WEBCL_PREF_ID__ALLOWED, mObserver);
+    if (NS_FAILED (rv))
+      D_LOG (LOG_LEVEL_WARNING, "Failed to unregister preference observer.");
+  }
+}
+
+
+NS_IMETHODIMP WebCL::GetTypes(JSContext *cx, nsIVariant **aTypes NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aTypes);
+  if (!mTypes)
+  {
+    nsresult rv = WebCL_createTypesObject (cx, getter_AddRefs (mTypes));
+    NS_ENSURE_SUCCESS (rv, rv);
+  }
+  NS_ADDREF (*aTypes = mTypes);
+  return NS_OK;
+}
+
+
+NS_IMETHODIMP WebCL::GetVersion(JSContext *cx, nsIVariant **aVersion NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aVersion);
+  if (!mVersion)
+ {
+    nsresult rv = WebCL_createVersionObject (0, getter_AddRefs (mVersion));
+    NS_ENSURE_SUCCESS (rv, rv);
+  }
+  NS_ADDREF (*aVersion = mVersion);
+  return NS_OK;
+}
+
+
+/* nsIVariant getPlatformIDs (); */
+NS_IMETHODIMP WebCL::GetPlatformIDs(JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  return GetPlatforms (cx, _retval);
+}
+
+/* nsIVariant getPlatforms (); */
+NS_IMETHODIMP WebCL::GetPlatforms(JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+
+  WEBCL_ENSURE_USE_PERMITTED;
+  NS_ENSURE_ARG_POINTER (_retval);
+  WEBCL_ENSURE_LIB_LOADED ();
+  nsresult rv;
+
+  nsTArray<cl_platform_id> platforms;
+  cl_int err = mWrapper->getPlatformIDs (platforms);
+  if (mWrapper->status() != WebCL_LibCLWrapper::SUCCESS)
+  {
+    // TODO: report detailed error to user
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+  if (CL_FAILED (err))
+  {
+    WebCL_reportJSError (cx, "WebCL::getPlatforms Failed with error %d.", err);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  if (platforms.IsEmpty ())
+  {
+    D_LOG (LOG_LEVEL_WARNING, "No platforms found.");
+    // This is not an error, so we'll return an empty array anyway.
+  }
+
+  nsCOMPtr<nsIVariant> value;
+  rv = WebCL_convertVectorToJSArrayInVariant (cx, platforms,
+                                              types::PLATFORM_V,
+                                              getter_AddRefs (value),
+                                              (WebCL_LibCLWrapper*)mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = value);
+
+  return NS_OK;
+}
+
+
+/** Convert a JSArray of values or JSObjects to C array of cl_context_properties.
+ * Designed to be compatible with ContextWrapper::createContext,
+ * ContextWrapper::createContextFromType, clCreateContext and
+ * clCreateContextFromType.
+ * \param aProperties An input JSArray. Items must be integers or WebCLPlatform
+ * instances where applicable.
+ * \param aResultOut Out-pointer for result. Result may be NULL even when
+ * return value is NS_OK if there were no properties in aProperties.
+ * \return NS error code or NS_OK on success.
+ */
+static nsresult convertContextProperties (JSContext *cx, nsIVariant *aProperties,
+                                          cl_context_properties** aResultOut)
+{
+  D_METHOD_START;
+  nsresult rv;
+  NS_ENSURE_ARG_POINTER (aProperties);
+
+  nsTArray<nsIVariant*> elements;
+  rv = WebCL_getVariantsFromJSArray (cx, aProperties, elements);
+  if (NS_FAILED (rv))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to get elements from argument aProperties. (rv %d)", rv);
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  cl_context_properties* clProperties = 0;
+
+  if (!elements.IsEmpty ())
+  {
+    clProperties =  (cl_context_properties*)malloc(sizeof (cl_context_properties)
+                                                   * (elements.Length () + 1));
+    if (!clProperties)
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Memory allocation failed.");
+      WebCL_releaseVariantVector (elements);
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    size_t cnt = 0;
+    rv = NS_OK;
+    for (nsTArray<nsIVariant*>::index_type i = 0; i < elements.Length(); ++i)
+    {
+      if (!elements[i])
+      {
+        D_LOG (LOG_LEVEL_ERROR, "Invalid non-variant element at position %d.", cnt+1);
+        rv = NS_ERROR_FAILURE;
+        break;
+      }
+
+      // Check expected non-integer types based previously converted property.
+      if (cnt > 0 && clProperties[cnt - 1] == CL_CONTEXT_PLATFORM)
+      {
+        // Expected object: IWebCLPlatform
+        nsCOMPtr<nsISupports> isu;
+        rv = elements[i]->GetAsISupports (getter_AddRefs(isu));
+        if (NS_FAILED (rv))
+        {
+          // TODO: this error message is probably lost
+          WebCL_reportJSError (cx, "Expected nsISupports element at position %d.", i + 1);
+          D_LOG (LOG_LEVEL_ERROR,
+                 "Expected nsISupports element at position %d. (rv %d)", i+1, rv);
+          break;
+        }
+        nsCOMPtr<WebCLPlatform> platform = do_QueryInterface (isu, &rv);
+        if (NS_FAILED (rv))
+        {
+          // TODO: this error message is probably lost
+          WebCL_reportJSError (cx, "Failed to convert element at position %d to WebCLPlatform.", i + 1);
+          D_LOG (LOG_LEVEL_ERROR,
+                 "Failed to convert element at position %d to WebCLPlatform. (rv %d)",
+                 i+1, rv);
+          break;
+        }
+
+        clProperties[cnt++] = (cl_context_properties) (platform->getInternal ());
+
+      }
+      else
+      {
+        // We generally assume all values are integers unless some other type
+        // is required by property id.
+        PRInt32 val = 0;
+        rv = elements[i]->GetAsInt32 (&val);
+        if (NS_FAILED (rv))
+        {
+          D_LOG (LOG_LEVEL_ERROR,
+                "Unexpected non-integer element at position %d. (rv %d)",
+                i+1, rv);
+          break;
+        }
+        clProperties[cnt++] = (cl_context_properties)val;
+      }
+
+    }
+
+    // Release variants
+    WebCL_releaseVariantVector (elements);
+    elements.Clear ();
+
+    // Handle errors from within the previous loop.
+    if (NS_FAILED (rv))
+    {
+      return rv;
+    }
+
+    clProperties [cnt] = 0;
+  }
+
+  if (aResultOut)
+    *aResultOut = clProperties;
+
+  return NS_OK;
+}
+
+
+/* Ensure that the OpenCL platform version of a device is at least 1.1.
+ */
+static nsresult ensureDeviceCLVersion (JSContext *cx, WebCL_LibCLWrapper* aLib,
+                                       cl_device_id aDevice)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aDevice);
+  nsresult rv;
+
+  cl_int err = CL_SUCCESS;
+
+  // Get name for error message purposes.
+  nsCString name;
+  aLib->getDeviceInfo (aDevice, CL_DEVICE_NAME, name);
+  // Failure is OK here, though unexpected.
+
+  // Get a char* to name so we can use it more directly.
+  // Note: The memory is owned by nsCString!
+  char const* const cName = name.get();
+
+  // NOTE: We need to check the platform version string instead of the device
+  //       version string. The latter is given from the point of view of
+  //       device capabilities and may be limited to 1.0 even when the 1.1
+  //       features we're interested in are there anyway.
+
+  cl_platform_id platform;
+  err = aLib->getDeviceInfo (aDevice, CL_DEVICE_PLATFORM, platform);
+  if (CL_FAILED (err))
+  {
+    WebCL_reportJSError (cx, "Failed to get platform object for device %s. (err %d)", cName, err);
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCString versionStr;
+  err = aLib->getPlatformInfo (platform, CL_PLATFORM_VERSION, versionStr);
+  if (CL_FAILED (err))
+  {
+    WebCL_reportJSError (cx, "Failed to get platform version for device %s. (err %d)", cName, err);
+    return NS_ERROR_FAILURE;
+  }
+
+  cl_int minor = 0, major = 0;
+  nsCString vendorInfo;
+  rv = WebCL_parseOpenCLVersion (versionStr, major, minor, vendorInfo);
+  if (NS_FAILED (rv))
+ {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to parse version string for device %s. (rv %d)", cName, rv);
+    WebCL_reportJSError (cx, "Failed to parse version string for device %s.", cName);
+    return rv;
+  }
+
+  // The OpenCL version must be 1.1 or more recent.
+  if ( !(major > 1 || minor >= 1))
+  {
+    D_LOG (LOG_LEVEL_ERROR,
+           "Platform version for device \"%s\" is \"%s\". WebCL requires OpenCL 1.1 or greater.",
+           cName, versionStr.get());
+    WebCL_reportJSError (cx, "Platform version for device \"%s\" is \"%s\". WebCL requires OpenCL 1.1 or greater.",
+                         cName, versionStr.get());
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  return NS_OK;
+}
+
+
+/* Ensure that the versions of devices on the context are at least OpenCL 1.1.
+ */
+static nsresult ensureContextDevicesCompatibility (JSContext *cx, WebCL_LibCLWrapper* aLib,
+                                                   cl_context aCtx)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aCtx);
+  nsresult rv = NS_OK;
+  nsTArray<cl_device_id> devices;
+
+  cl_int wrErr = aLib->getContextInfo (aCtx, CL_CONTEXT_DEVICES, devices);
+  if (CL_FAILED (wrErr))
+  {
+    return NS_ERROR_FAILURE;
+  }
+
+  for (nsTArray<cl_device_id>::index_type i = 0; i < devices.Length(); ++i)
+  {
+    rv = ensureDeviceCLVersion (cx, aLib, devices[i]);
+    if (NS_FAILED (rv))
+    {
+      break;
+    }
+  }
+  return rv;
+}
+
+
+/* IWebCLContext createContext (in nsIVariant aProperties, in nsIVariant aDevices); */
+NS_IMETHODIMP WebCL::CreateContext(nsIVariant *aProperties, nsIVariant *aDevices, JSContext *cx, IWebCLContext **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  WEBCL_ENSURE_USE_PERMITTED;
+  NS_ENSURE_ARG_POINTER (aProperties);
+  NS_ENSURE_ARG_POINTER (aDevices);
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  bool reported = false;
+
+  // Devices
+  nsTArray<nsIVariant*> deviceVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aDevices, deviceVariants);
+  if (NS_FAILED (rv))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to get elements from argument aDevices. (rv %d)", rv);
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  nsTArray<cl_device_id> devices;
+  devices.SetCapacity (deviceVariants.Length ());
+  if (!deviceVariants.IsEmpty ())
+  {
+    rv = NS_OK;
+    for (nsTArray<nsIVariant*>::index_type i = 0; i < deviceVariants.Length(); ++i)
+    {
+      if (!deviceVariants[i])
+      {
+        D_LOG (LOG_LEVEL_ERROR, "Invalid non-variant element in aDevices at position %d.", i+1);
+        WebCL_reportJSError (cx, "Invalid non-variant element in aDevices at position %d.", i+1);
+        reported = true;
+        rv = NS_ERROR_INVALID_ARG;
+        break;
+      }
+
+      nsCOMPtr<nsISupports> isu;
+      rv = deviceVariants[i]->GetAsISupports (getter_AddRefs(isu));
+      if (NS_FAILED (rv))
+      {
+        D_LOG (LOG_LEVEL_ERROR,
+               "Expected nsISupports element in aDevices at position %d. (rv %d)", i+1, rv);
+        WebCL_reportJSError (cx, "Expected nsISupports element in aDevices at position %d.", i+1);
+        reported = true;
+        break;
+      }
+      nsCOMPtr<WebCLDevice> device = do_QueryInterface (isu, &rv);
+      if (NS_FAILED (rv))
+      {
+        D_LOG (LOG_LEVEL_ERROR,
+               "Failed to convert element in aDevices at position %d to WebCLDevice. (rv %d)",
+               i+1, rv);
+        WebCL_reportJSError (cx, "Failed to convert element in aDevices at position %d to WebCLDevice.", i+1);
+        reported = true;
+        break;
+      }
+
+      devices.AppendElement (device->getInternal ());
+    }
+
+    // Release variants
+    WebCL_releaseVariantVector (deviceVariants);
+    deviceVariants.Clear ();
+
+    // Handle errors from within the previous loop.
+    if (NS_FAILED (rv))
+    {
+      return reported ? WEBCL_XPCOM_ERROR : rv;
+    }
+  }
+
+  // Context properties
+  cl_context_properties* clProperties = 0;
+  rv = convertContextProperties (cx, aProperties, &clProperties);
+  // TODO: fix error reporting
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  // Create context
+  cl_int err = CL_SUCCESS;
+  cl_context ctx = mWrapper->createContext (clProperties, devices, 0, 0, &err);
+
+  if (clProperties)
+    free (clProperties);
+
+  if (mWrapper->status() != WebCL_LibCLWrapper::SUCCESS)
+  {
+    // TODO: report detailed error to user
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+  if (CL_FAILED (err) || !ctx)
+  {
+    WebCL_reportJSError (cx, "%s Failed with error %d.", __FUNCTION__, err);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  // Ensure that the devices in this context are suitable for WebCL.
+  rv = ensureContextDevicesCompatibility (cx, mWrapper, ctx);
+  if (NS_FAILED (rv))
+  {
+    mWrapper->releaseContext (ctx);
+    // The error is reported in ensureContextDevicesCompatibility
+    return WEBCL_XPCOM_ERROR;
+  }
+
+  nsCOMPtr<WebCLContext> xpcObj;
+  rv = WebCLContext::getInstance (ctx, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+  return NS_OK;
+}
+
+
+/* IWebCLContext createContextFromType (in nsIArray aProperties, in T_WebCLDeviceType aDeviceType); */
+NS_IMETHODIMP WebCL::CreateContextFromType(nsIVariant *aProperties, T_WebCLDeviceType aDeviceType, JSContext *cx, IWebCLContext **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  WEBCL_ENSURE_USE_PERMITTED;
+  NS_ENSURE_ARG_POINTER (aProperties);
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  cl_context_properties* clProperties = 0;
+  rv = convertContextProperties (cx, aProperties, &clProperties);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  // Create context
+  cl_int err = CL_SUCCESS;
+  cl_context ctx = mWrapper->createContextFromType (clProperties, aDeviceType, 0, 0, &err);
+
+  if (clProperties)
+  {
+    free (clProperties);
+  }
+
+  if (mWrapper->status() != WebCL_LibCLWrapper::SUCCESS)
+  {
+    // TODO: report detailed error to user
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+  if (CL_FAILED (err) || !ctx)
+  {
+    WebCL_reportJSError (cx, "%s Failed with error %d.", __FUNCTION__, err);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  // Ensure that the devices in this context are suitable for WebCL.
+  rv = ensureContextDevicesCompatibility (cx, mWrapper, ctx);
+  if (NS_FAILED (rv))
+  {
+    mWrapper->releaseContext (ctx);
+    // The error is reported in ensureContextDevicesCompatibility
+    return WEBCL_XPCOM_ERROR;
+  }
+
+  nsCOMPtr<WebCLContext> xpcObj;
+  rv = WebCLContext::getInstance (ctx, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+  return NS_OK;
+}
+
+
+/* void waitForEvents (in nsIVariant aEventList); */
+NS_IMETHODIMP WebCL::WaitForEvents(nsIVariant *aEventList, JSContext *cx)
+{
+  D_METHOD_START;
+  WEBCL_ENSURE_USE_PERMITTED;
+  nsresult rv;
+
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> events;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         events);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  cl_int err = mWrapper->waitForEvents (events);
+  if (mWrapper->status() != WebCL_LibCLWrapper::SUCCESS)
+  {
+    // TODO: report detailed error to user
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+  if (CL_FAILED (err))
+  {
+    WebCL_reportJSError (cx, "%s Failed with error %d.", __FUNCTION__, err);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
+
+/* void unloadCompiler (); */
+NS_IMETHODIMP WebCL::UnloadCompiler(JSContext *cx)
+{
+  D_METHOD_START;
+  WEBCL_ENSURE_USE_PERMITTED;
+
+  cl_int err = mWrapper->unloadCompiler ();
+  if (mWrapper->status() != WebCL_LibCLWrapper::SUCCESS)
+  {
+    // TODO: report detailed error to user
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+  if (CL_FAILED (err))
+  {
+    WebCL_reportJSError (cx, "%s Failed with error %d.", __FUNCTION__, err);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
+
+
+// nsISecurityCheckedComponent
+
+NS_IMETHODIMP
+WebCL::CanCreateWrapper (const nsIID* aIID,
+                            char** _retval)
+{
+  D_METHOD_START;
+  WEBCL_ENSURE_USE_PERMITTED;
+  *_retval = NS_strdup (C_COM_SECURITY_ALL_ACCESS);
+  return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+}
+
+NS_IMETHODIMP
+WebCL::CanCallMethod (const nsIID* aIID, const PRUnichar* aMethodName,
+                        char** _retval)
+{
+  D_METHOD_START;
+  WEBCL_ENSURE_USE_PERMITTED;
+  NS_ENSURE_TRUE (_retval, NS_ERROR_NULL_POINTER);
+  *_retval = NS_strdup (C_COM_SECURITY_ALL_ACCESS);
+  return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+}
+
+NS_IMETHODIMP
+WebCL::CanGetProperty (const nsIID* aIID, const PRUnichar* aPropertyName,
+                          char** _retval)
+{
+  D_METHOD_START;
+  WEBCL_ENSURE_USE_PERMITTED;
+  NS_ENSURE_TRUE (_retval, NS_ERROR_NULL_POINTER);
+  *_retval = NS_strdup (C_COM_SECURITY_ALL_ACCESS);
+  return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+}
+
+NS_IMETHODIMP
+WebCL::CanSetProperty (const nsIID* aIID, const PRUnichar* aPropertyName,
+                          char** _retval)
+{
+  D_METHOD_START;
+  WEBCL_ENSURE_USE_PERMITTED;
+  NS_ENSURE_TRUE (_retval, NS_ERROR_NULL_POINTER);
+  *_retval = NS_strdup (C_COM_SECURITY_NO_ACCESS);
+  return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+}
+
+
+// Called from WebCLObserver
+nsresult WebCL::preferenceChanged (nsISupports* aSubject, const char* aTopic, const PRUnichar* aData)
+{
+  D_METHOD_START;
+  nsresult rv = NS_OK;
+  if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID))
+  {
+    nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(aSubject);
+    if (!branch)
+    {
+      D_LOG (LOG_LEVEL_ERROR, "No preference branch!");
+      return NS_ERROR_FAILURE;
+    }
+
+    // extensions.webcl.allowed
+    PRInt32 val = WEBCL_PREF_VALUE__ALLOWED__NOT_SET;
+    rv = branch->GetIntPref(WEBCL_PREF_ID__ALLOWED, &val);
+    if (NS_SUCCEEDED(rv))
+    {
+      if (val == WEBCL_PREF_VALUE__ALLOWED__NOT_SET)
+      {
+        mWebCLSecurityDialogNeeded = true;
+      }
+      else if (val == WEBCL_PREF_VALUE__ALLOWED__FALSE || val == WEBCL_PREF_VALUE__ALLOWED__TRUE)
+      {
+        mWebCLUsePermitted = (bool)val;
+        mWebCLSecurityDialogNeeded = false;
+      }
+      else
+      {
+        D_LOG (LOG_LEVEL_ERROR, "Unexpected value for preferense " WEBCL_PREF_ID__ALLOWED);
+      }
+    }
+    else
+    {
+      D_LOG (LOG_LEVEL_WARNING, "failed to read preference %s: %d", WEBCL_PREF_ID__ALLOWED, rv);
+    }
+
+  }
+
+  // extensions.webcl.opencllib
+  // We don't handle the actual value here but just enable the library loading
+  // to be retried just.
+  mLibLoadFailed = false;
+
+  return NS_OK;
+}
+
+
+// Private & protected methods
+
+nsresult WebCL::loadLibrary (JSContext *cx)
+{
+  if (mWrapper && mWrapper->library())
+  {
+    // Library OK
+    return NS_OK;
+  }
+
+  nsresult rv;
+  nsCOMPtr<nsIPrefBranch2> branch = do_GetService (NS_PREFSERVICE_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+  nsCString settingsLibPath;
+  rv = branch->GetCharPref(WEBCL_PREF_ID__OCLLIB, getter_Copies(settingsLibPath));
+  char const* libPath = 0;
+  if (NS_SUCCEEDED(rv))
+  {
+    D_LOG (LOG_LEVEL_DEBUG, "%s: %s",WEBCL_PREF_ID__OCLLIB, settingsLibPath.get());
+    libPath = settingsLibPath.get();
+  }
+  else
+  {
+    rv = branch->SetCharPref(WEBCL_PREF_ID__OCLLIB, "");
+    D_LOG (LOG_LEVEL_DEBUG, "%s: \"\"  (created as default)",WEBCL_PREF_ID__OCLLIB);
+    libPath = "";
+  }
+
+  if (strlen(libPath) == 0)
+  {
+    libPath = "OpenCL";
+  }
+
+  nsCString errStr;
+  nsCOMPtr<WebCL_LibCL> libCL;
+  if (!WebCL_LibCL::load(libPath, getter_AddRefs(libCL), &errStr))
+  {
+    mWrapper = 0;
+    mLibLoadFailed = true;
+
+    if (cx)
+    {
+      WebCL_reportJSError (cx, "Failed to load OpenCL library \"%s\": %s",
+                           libPath, errStr.get());
+      return WEBCL_XPCOM_ERROR;
+    }
+
+    return NS_ERROR_FAILURE;
+  }
+
+  mWrapper = new WebCL_LibCLWrapper (libCL);
+  mLibLoadFailed = false;
+
+  return NS_OK;
+}
+
+
+nsresult WebCL::showSecurityPrompt ()
+{
+  D_METHOD_START;
+  nsresult rv;
+
+  // Deny use if prompter fails.
+  mWebCLUsePermitted = false;
+
+  nsCOMPtr<nsIPrompt> prompter;
+  nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv));
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  rv = wwatch->GetNewPrompter(0, getter_AddRefs(prompter));
+  if (NS_FAILED (rv) || !prompter)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to get prompt service.");
+    return NS_FAILED(rv) ? rv : NS_ERROR_FAILURE;
+  }
+
+  // Default to deny. Just in case the dialog fails somehow..
+  bool response = false;
+  bool makePermanent = false;
+
+  nsCOMPtr<nsIPrefBranch2> branch = do_GetService (NS_PREFSERVICE_CONTRACTID, &rv);
+  PRInt32 val = WEBCL_PREF_VALUE__ALLOWED__NOT_SET;
+  if (NS_SUCCEEDED(rv) && branch)
+  {
+    rv = branch->GetIntPref(WEBCL_PREF_ID__ALLOWED, &val);
+  }
+  if (NS_FAILED (rv))
+  {
+    D_LOG (LOG_LEVEL_WARNING, "Failed to access preferences.");
+  }
+  makePermanent = (val == WEBCL_PREF_VALUE__ALLOWED__NOT_SET ? PR_FALSE : PR_TRUE);
+
+
+  nsString msg = NS_LITERAL_STRING("WARNING! This WebCL implementation is experimental and");
+  msg.Append(NS_LITERAL_STRING(" is likely to introduce severe security vulnerabilities"));
+  msg.Append(NS_LITERAL_STRING(" in your system. Use it cautiously and at your own risk."));
+  msg.Append(NS_LITERAL_STRING(" This setting is also available in Advanced Settings"));
+  msg.Append(NS_LITERAL_STRING(" (about:config) as "));
+  msg.Append(NS_LITERAL_STRING(WEBCL_PREF_ID__ALLOWED));
+  msg.Append(NS_LITERAL_STRING(" ."));
+  rv = prompter->ConfirmCheck(NS_LITERAL_STRING("WebCL security warning").get(),
+                              msg.get (),
+                              NS_LITERAL_STRING("Remember this setting.").get(),
+                              &makePermanent,
+                              &response);
+  if (NS_SUCCEEDED (rv))
+  {
+    mWebCLUsePermitted = (bool)response;
+    mWebCLSecurityDialogNeeded = false;
+
+    if (makePermanent && branch)
+    {
+      PRInt32 val = (mWebCLUsePermitted ? WEBCL_PREF_VALUE__ALLOWED__TRUE : WEBCL_PREF_VALUE__ALLOWED__FALSE);
+      rv = branch->SetIntPref(WEBCL_PREF_ID__ALLOWED, val);
+      if (NS_FAILED (rv))
+        D_LOG (LOG_LEVEL_ERROR, "Failed to set preference " WEBCL_PREF_ID__ALLOWED);
+    }
+  }
+
+  return rv;
+}
+
diff -r 450143d2d810 browser/components/webcl/src/WebCL.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCL.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,83 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \file WebCL.h
+ * WebCL class and component definition.
+ * \see IWebCL
+ */
+#ifndef _WEBCL_H_
+#define _WEBCL_H_
+
+#define WEBCL_CLASSNAME "WebCL"
+#define WEBCL_CID { 0x8d1a0db2, 0x94af, 0x4333, { 0x9b, 0x55, 0x9c, 0x51, 0x6a, 0x1d, 0xbb, 0xea } }
+#define WEBCL_CONTRACTID "@webcl.nokiaresearch.com/WebCL;1"
+
+#include "IWebCL.h" // Generated from IWebCL.idl
+
+#include "WebCLCommon.h"
+#include "WebCLObserver.h"
+
+#include "nsIVariant.h"
+#include "nsCOMPtr.h"
+
+
+/** Implements IWebCL interface. */
+class WebCL : public IWebCL, public WebCLCommon
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISECURITYCHECKEDCOMPONENT
+  NS_DECL_IWEBCL
+
+  WebCL();
+  nsresult preferenceChanged (nsISupports* aSubject, const char* aTopic, const PRUnichar* aData);
+
+private:
+  virtual ~WebCL();
+
+  nsresult loadLibrary (JSContext *cx);
+  nsresult showSecurityPrompt ();
+
+  nsCOMPtr<nsIVariant> mTypes;
+  nsCOMPtr<nsIVariant> mVersion;
+
+  // True if the user has explicitly permitted WebCL to be used.
+  // The value should only be changed as result of showSecurityPrompt() call or
+  // based on preferences
+  bool mWebCLUsePermitted;
+
+  // True if the security dialog has not been shown but it should.
+  bool mWebCLSecurityDialogNeeded;
+
+  bool mLibLoadFailed;
+
+  nsCOMPtr<WebCLObserver> mObserver;
+};
+
+#endif // _WEBCL_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCLCommandQueue.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLCommandQueue.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,1558 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCLCommandQueue.h"
+#include "WebCLCommon.h"
+#include "WebCL_internal.h"
+#include "WebCL_clwrapper.h"
+
+#include "nsXPCOM.h"
+#include "nsError.h"
+#include "nsComponentManagerUtils.h"
+#include "nsISecurityCheckedComponent.h"
+#include "nsIRunnable.h"
+#include "nsIThread.h"
+#include "nsThreadUtils.h"
+
+#include "jsapi.h"
+#include "jsproxy.h"
+#include "jswrapper.h"
+#include "jsfriendapi.h"
+
+
+NS_IMPL_ISUPPORTS2 (WebCLCommandQueue, IWebCLCommandQueue, nsISecurityCheckedComponent)
+WEBCL_SECURITY_CHECKED_IMPL (WebCLCommandQueue)
+
+
+/* static */
+InstanceRegistry<cl_command_queue, WebCLCommandQueue*> WebCLCommandQueue::instanceRegistry;
+
+
+/* static */
+nsresult WebCLCommandQueue::getInstance (cl_command_queue aInternal, WebCLCommandQueue** aResultOut,
+                                         WebCL_LibCLWrapper* aLibWrapper)
+{
+  nsresult rv = NS_OK;
+
+  WebCLCommandQueue* existing = 0;
+  if (instanceRegistry.findById (aInternal, &existing))
+  {
+    NS_IF_ADDREF (*aResultOut = existing);
+  }
+  else
+  {
+    nsCOMPtr<WebCLCommandQueue> obj = do_CreateInstance (WEBCL_COMMANDQUEUE_CONTRACTID, &rv);
+    if (NS_FAILED (rv))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to create instance. rv=%d.", rv);
+      return rv;
+    }
+
+    obj->setWrapper (aLibWrapper);
+    obj->mInternal = aInternal;
+
+    instanceRegistry.add (obj->mInternal, obj);
+
+    NS_IF_ADDREF (*aResultOut = obj);
+  }
+
+  return rv;
+}
+
+
+WebCLCommandQueue::WebCLCommandQueue()
+  : IWebCLCommandQueue(), WebCLCommon(),
+    mInternal(0)
+{
+  D_METHOD_START;
+}
+
+
+WebCLCommandQueue::~WebCLCommandQueue()
+{
+  D_METHOD_START;
+  if (mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (mWrapper)
+      mWrapper->releaseCommandQueue (mInternal);
+    mInternal = 0;
+  }
+
+}
+
+
+int WebCLCommandQueue::getTypeForInfoName (int aName)
+{
+  D_METHOD_START;
+  switch (aName)
+  {
+    case CL_QUEUE_CONTEXT: return types::CONTEXT;
+    case CL_QUEUE_DEVICE: return types::DEVICE;
+    case CL_QUEUE_REFERENCE_COUNT: return types::UINT;
+    case CL_QUEUE_PROPERTIES: return types::COMMAND_QUEUE_PROPERTIES;
+    default: ;
+  }
+  return types::UNKNOWN;
+}
+
+
+/* nsIVariant getCommandQueueInfo (in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLCommandQueue::GetCommandQueueInfo(PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  WEBCL_GETINFO_MEDIATOR_SWITCH (aName, type, mWrapper, getCommandQueueInfo, mInternal,
+                                 variant, err, rv);
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
+
+
+/* IWebCLEvent enqueueNDRangeKernel (in nsISupports aKernel, in unsigned long aWorkDim, in nsIVariant aGlobalWorkOffset, in nsIVariant aGlobalWorkSize, in nsIVariant aLocalWorkSize, [optional] in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueNDRangeKernel(nsISupports *aKernel, PRUint32 aWorkDim, nsIVariant *aGlobalWorkOffset, nsIVariant *aGlobalWorkSize, nsIVariant *aLocalWorkSize, nsIVariant *aEventWaitList, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aKernel);
+  NS_ENSURE_ARG_POINTER (aGlobalWorkOffset);
+  NS_ENSURE_ARG_POINTER (aGlobalWorkSize);
+  NS_ENSURE_ARG_POINTER (aLocalWorkSize);
+  NS_ENSURE_ARG_POINTER (aEventWaitList);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+
+  nsTArray<nsIVariant*> variants;
+  nsTArray<size_t> globalOffset;
+  nsTArray<size_t> globalSize;
+  nsTArray<size_t> localSize;
+
+  // Global work offset vector
+  rv = WebCL_getVariantsFromJSArray (cx, aGlobalWorkOffset, variants);
+  NS_ENSURE_SUCCESS (rv, rv);
+  globalOffset.SetCapacity (variants.Length());
+  for (nsTArray<size_t>::index_type i = 0; i < variants.Length(); ++i)
+  {
+    PRUint32 val;
+    rv = variants[i]->GetAsUint32 (&val);
+    if (NS_FAILED (rv))
+    {
+      WebCL_reportJSError (cx, "%s: Failed to convert 3rd argument to an array of integers.",
+                           __FUNCTION__);
+      break;
+    }
+    globalOffset.AppendElement (val);
+  }
+  WebCL_releaseVariantVector (variants);
+  if (NS_FAILED (rv))
+  {
+    // Error reported by WebCL_reportJSError above.
+    return WEBCL_XPCOM_ERROR;
+  }
+
+  // Global work size vector
+  rv = WebCL_getVariantsFromJSArray (cx, aGlobalWorkSize, variants);
+  NS_ENSURE_SUCCESS (rv, rv);
+  globalSize.SetCapacity (variants.Length());
+  for (nsTArray<size_t>::index_type i = 0; i < variants.Length(); ++i)
+  {
+    PRUint32 val;
+    rv = variants[i]->GetAsUint32 (&val);
+    if (NS_FAILED (rv))
+    {
+      WebCL_reportJSError (cx, "%s: Failed to convert 4th argument to an array of integers.",
+                           __FUNCTION__);
+      break;
+    }
+    globalSize.AppendElement (val);
+  }
+  WebCL_releaseVariantVector (variants);
+  if (NS_FAILED (rv))
+  {
+    // Error reported by WebCL_reportJSError above.
+    return WEBCL_XPCOM_ERROR;
+  }
+
+  // Local work size vector
+  rv = WebCL_getVariantsFromJSArray (cx, aLocalWorkSize, variants);
+  NS_ENSURE_SUCCESS (rv, rv);
+  localSize.SetCapacity (variants.Length());
+  for (nsTArray<size_t>::index_type i = 0; i < variants.Length(); ++i)
+  {
+    PRUint32 val;
+    rv = variants[i]->GetAsUint32 (&val);
+    if (NS_FAILED (rv))
+    {
+      WebCL_reportJSError (cx, "%s: Failed to convert 5th argument to an array of integers.",
+                           __FUNCTION__);
+      break;
+    }
+    localSize.AppendElement (val);
+  }
+  WebCL_releaseVariantVector (variants);
+  if (NS_FAILED (rv))
+  {
+    // Error reported by WebCL_reportJSError above.
+    return WEBCL_XPCOM_ERROR;
+  }
+
+
+  // Event list
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventWaitList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> eventList;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         eventList);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  // Kernel
+  nsCOMPtr<WebCLKernel> kernel = do_QueryInterface (aKernel, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  cl_event event;
+  cl_int err = mWrapper->enqueueNDRangeKernel (mInternal, kernel->getInternal(),
+                                               aWorkDim, globalOffset, globalSize, localSize,
+                                               eventList, &event);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLEvent enqueueTask (in nsISupports aKernel, [optional] in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueTask(nsISupports *aKernel, nsIVariant *aEventWaitList, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aKernel);
+  NS_ENSURE_ARG_POINTER (aEventWaitList);
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  // Kernel
+  nsCOMPtr<WebCLKernel> kernel = do_QueryInterface (aKernel, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  // Event list
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventWaitList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> eventList;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         eventList);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  cl_event event;
+  cl_int err = mWrapper->enqueueTask (mInternal, kernel->getInternal(),
+                                      eventList, &event);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+class HolderReleaserRunnable : public nsIRunnable
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIRUNNABLE
+  HolderReleaserRunnable (nsIXPConnectJSObjectHolder* target) : m_target(target) { }
+private:
+  nsIXPConnectJSObjectHolder* m_target;
+};
+
+NS_IMPL_THREADSAFE_ISUPPORTS1 (HolderReleaserRunnable, nsIRunnable);
+
+NS_IMETHODIMP HolderReleaserRunnable::Run ()
+{
+  NS_RELEASE (m_target);
+  return NS_OK;
+}
+
+
+static void* packBufferDataHolderUnrefCbUserData (WebCL_LibCLWrapper* aLibWrapper,
+                                                  nsIXPConnectJSObjectHolder* aHolder)
+{
+  void** res = (void**)malloc (sizeof(void*) * 2);
+  if (res)
+  {
+    res[0] = (void*)aLibWrapper;
+    res[1] = (void*)aHolder;
+  }
+  return res;
+}
+
+static void unpackBufferDataHolderUnrefCbUserData (void** aUserData,
+                                                   WebCL_LibCLWrapper** aLibWrapperOut,
+                                                   nsIXPConnectJSObjectHolder** aHolderOut)
+{
+  if (aUserData)
+  {
+    if (aLibWrapperOut)
+      *aLibWrapperOut = (WebCL_LibCLWrapper*)aUserData[0];
+    if (aHolderOut)
+      *aHolderOut = (nsIXPConnectJSObjectHolder*)aUserData[1];
+  }
+}
+
+void CL_CALLBACK bufferDataHolderUnrefCb(cl_event event, cl_int event_command_exec_status, void *user_data)
+{
+  D_METHOD_START;
+  // The user_data should always be nsIXPConnectJSObjectHolder pointer.
+  // TODO: Is it possible that this this function is called multiple times for the same event?
+  if (user_data && event_command_exec_status == CL_COMPLETE)
+  {
+    WebCL_LibCLWrapper* libWrapper = 0;
+    nsIXPConnectJSObjectHolder* holder = 0;
+    unpackBufferDataHolderUnrefCbUserData ((void**)user_data, &libWrapper, &holder);
+
+    // Ensure the holder XPCOM object is released in the main thread
+    nsCOMPtr<HolderReleaserRunnable> runnable ( new HolderReleaserRunnable (holder));
+    if (!runnable || NS_FAILED (NS_DispatchToMainThread (runnable)))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to dispatch releaser runnable for JS object holder.");
+    }
+
+    // Release the OpenCL event
+    // We took an extra ref on the event when setting up this callback to
+    // ensure that the object is not released too early.
+    libWrapper->releaseEvent (event);
+    NS_RELEASE (libWrapper);
+
+    free (user_data);
+  }
+}
+
+
+static nsresult variantTypedArrayToData (JSContext* cx, nsIVariant* aTypedArrayVariant,
+                                         void** aDataOut, size_t* aLengthOut,
+                                         nsIXPConnectJSObjectHolder** aHolderOut = 0)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (aTypedArrayVariant);
+  NS_ENSURE_ARG_POINTER (aDataOut);
+  NS_ENSURE_ARG_POINTER (aLengthOut);
+
+  void* data = 0;
+  size_t length = 0;
+  nsresult rv;
+
+  PRUint16 variantType = 0;
+  rv = aTypedArrayVariant->GetDataType (&variantType);
+  if ( !(variantType == nsIDataType::VTYPE_INTERFACE
+         || variantType == nsIDataType::VTYPE_INTERFACE_IS))
+  {
+      D_LOG (LOG_LEVEL_ERROR, "Invalid variant type.");
+      WebCL_reportJSError (cx, "%s: Invalid typed array argument"
+                               "(variant type %d).", __FUNCTION__, variantType);
+      return NS_ERROR_INVALID_ARG;
+  }
+
+  if (!cx)
+  {
+    nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv);
+    NS_ENSURE_SUCCESS (rv, rv);
+    cx = stack->GetSafeJSContext ();
+    NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE);
+  }
+
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+  js::Value jsVal;
+  rv = xpc->VariantToJS(cx, JS_GetGlobalObject(cx), aTypedArrayVariant, &jsVal);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ENSURE_TRUE (jsVal.isObject(), NS_ERROR_INVALID_ARG);
+
+  JSObject* jsObj = jsVal.toObjectOrNull();
+  if (jsObj && js::IsObjectProxy (jsObj))
+  {
+    jsObj = js::UnwrapObject (jsObj);
+  }
+
+  if (!jsObj || !JS_IsTypedArrayObject (jsObj, cx))
+  {
+    WebCL_reportJSError (cx, "%s: Invalid typed array argument (not typed array).",
+                         __FUNCTION__);
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  data = JS_GetArrayBufferViewData (jsObj, cx);
+  D_LOG (LOG_LEVEL_DEBUG, "TypedArray data pointer: %p", data);
+  if (!data)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Typed array has no data.");
+    WebCL_reportJSError (cx, "WebCLCommandQueue::enqueueWriteBuffer: Typed array has no data.");
+    return NS_ERROR_INVALID_ARG;
+  }
+  length = JS_GetArrayBufferViewByteLength (jsObj, cx);
+  D_LOG (LOG_LEVEL_DEBUG, "TypedArray data length: %d bytes", length);
+
+  if (aHolderOut)
+  {
+    rv = xpc->HoldObject (cx, jsObj, aHolderOut);
+    NS_ENSURE_SUCCESS (rv, rv);
+  }
+
+  if (aDataOut)
+    *aDataOut = data;
+  if (aLengthOut)
+    *aLengthOut = length;
+
+  return NS_OK;
+}
+
+
+/* IWebCLEvent enqueueWriteBuffer (in nsISupports aBuffer, in boolean aBlockingWrite, in T_WebCLSize aOffset, in T_WebCLSize aSize, in nsIVariant aData, [optional] in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueWriteBuffer(nsISupports *aBuffer, bool aBlockingWrite, T_WebCLSize aOffset, T_WebCLSize aSize, nsIVariant *aData, nsIVariant *aEventWaitList, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aBuffer);
+  NS_ENSURE_ARG_POINTER (aData);
+  NS_ENSURE_ARG_POINTER (aEventWaitList);
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsCOMPtr<WebCLMemoryObject> buffer = do_QueryInterface (aBuffer, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  void* data = 0;
+  size_t length = 0;
+  // The holder ensures that the JSObject (typed array or dataobject) isn't
+  // garbage collected before the enqueued operation finishes.
+  nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
+
+  rv = variantTypedArrayToData (cx, aData, &data, &length, getter_AddRefs(holder));
+  NS_ENSURE_SUCCESS (rv, WEBCL_XPCOM_ERROR);
+  if (aSize > length)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "aSize %d exceeds data buffer length %d.", aSize, length);
+    WebCL_reportJSError (cx, "aSize exceeds data buffer length.");
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  // Event wait list
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventWaitList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> eventList;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         eventList);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  cl_event event;
+  cl_int err = mWrapper->enqueueWriteBuffer (mInternal, buffer->getInternal(),
+                                             aBlockingWrite, aOffset, aSize, data,
+                                             eventList, &event);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  // Holder for async operations
+  if (!aBlockingWrite)
+  {
+    // The holder object must be addreffed so it's not automatically released by
+    // nsCOMPtr. The holder ensures that GC doesn't collect the JSObject that
+    // owns the target memory (data).
+    NS_ADDREF (holder);
+
+    // Take an extra ref on the event to ensure it's not released before
+    // the callback is invoked.
+    mWrapper->retainEvent (event);
+
+    void* userData = packBufferDataHolderUnrefCbUserData (mWrapper, holder);
+
+    if (userData)
+    {
+      NS_ADDREF (mWrapper);
+
+      // The holder is released in an event callback when the event has completed.
+      err = mWrapper->setEventCallback (event, CL_COMPLETE, bufferDataHolderUnrefCb,
+                                        userData);
+      if (mWrapper->status() != WebCL_LibCLWrapper::SUCCESS || CL_FAILED (err))
+      {
+        D_LOG (LOG_LEVEL_ERROR, "setEventCallback failed with error %d.", err);
+        NS_RELEASE (holder);
+        mWrapper->releaseEvent (event);
+      }
+    }
+    else
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to pack user data for event cb: "
+      "Memory allocation failure?");
+      NS_RELEASE (holder);
+      mWrapper->releaseEvent (event);
+    }
+  }
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLEvent enqueueReadBuffer (in nsISupports aBuffer, in boolean aBlockingRead, in T_WebCLSize aOffset, in T_WebCLSize aSize, in nsIVariant aData, [optional] in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueReadBuffer(nsISupports *aBuffer, bool aBlockingRead, T_WebCLSize aOffset, T_WebCLSize aSize, nsIVariant *aData, nsIVariant *aEventWaitList, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aBuffer);
+  NS_ENSURE_ARG_POINTER (aData);
+  NS_ENSURE_ARG_POINTER (aEventWaitList);
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsCOMPtr<WebCLMemoryObject> buffer = do_QueryInterface (aBuffer, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  void* data = 0;
+  size_t length = 0;
+  nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
+  rv = variantTypedArrayToData (cx, aData, &data, &length, getter_AddRefs(holder));
+  NS_ENSURE_SUCCESS (rv, WEBCL_XPCOM_ERROR);
+
+  // The array buffer is expected to have sufficient size for
+  // incoming data. If this is not the case, then we'll throw an error.
+  if (aSize > length)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "aSize %d exceeds data buffer length %d.", aSize, length);
+    WebCL_reportJSError (cx, "%s: aSize exceeds data buffer length.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  // Event wait list
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventWaitList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> eventList;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         eventList);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  cl_event event;
+  cl_int err = mWrapper->enqueueReadBuffer (mInternal, buffer->getInternal(),
+                                            aBlockingRead, aOffset, aSize, data,
+                                            eventList, &event);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  // Holder for async operations, see EnqueueWriteBuffer for details
+  if (!aBlockingRead)
+  {
+    NS_ADDREF (holder);
+    mWrapper->retainEvent (event);
+    void* userData = packBufferDataHolderUnrefCbUserData (mWrapper, holder);
+    if (userData)
+    {
+      NS_ADDREF (mWrapper);
+
+      err = mWrapper->setEventCallback (event, CL_COMPLETE, bufferDataHolderUnrefCb,
+                                        userData);
+      if (mWrapper->status() != WebCL_LibCLWrapper::SUCCESS || CL_FAILED (err))
+      {
+        D_LOG (LOG_LEVEL_ERROR, "setEventCallback failed with error %d.", err);
+        NS_RELEASE (holder);
+        mWrapper->releaseEvent (event);
+      }
+    }
+    else
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to pack user data for event cb: "
+      "Memory allocation failure?");
+      NS_RELEASE (holder);
+      mWrapper->releaseEvent (event);
+    }
+  }
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLEvent enqueueWriteBufferRect (in nsISupports aBuffer, in boolean aBlockingWrite, in nsIVariant aBufferOrigin, in nsIVariant aHostOrigin, in nsIVariant aRegion, in T_WebCLSize aBufferRowPitch, in T_WebCLSize aBufferSlicePitch, in T_WebCLSize aHostRowPitch, in T_WebCLSize aHostSlicePitch, in nsIVariant aData, [optional] in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueWriteBufferRect(nsISupports *aBuffer, bool aBlockingWrite, nsIVariant *aBufferOrigin, nsIVariant *aHostOrigin, nsIVariant *aRegion, T_WebCLSize aBufferRowPitch, T_WebCLSize aBufferSlicePitch, T_WebCLSize aHostRowPitch, T_WebCLSize aHostSlicePitch, nsIVariant *aData, nsIVariant *aEventWaitList, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aBuffer);
+  NS_ENSURE_ARG_POINTER (aBufferOrigin);
+  NS_ENSURE_ARG_POINTER (aHostOrigin);
+  NS_ENSURE_ARG_POINTER (aRegion);
+  NS_ENSURE_ARG_POINTER (aData);
+  NS_ENSURE_ARG_POINTER (aEventWaitList);
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsCOMPtr<WebCLMemoryObject> buffer = do_QueryInterface (aBuffer, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  nsTArray<size_t> bufOrigin;
+  rv = WEBCL_variantToOrigin (cx, aBufferOrigin, bufOrigin);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: buffer origin is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  nsTArray<size_t> hostOrigin;
+  rv = WEBCL_variantToOrigin (cx, aHostOrigin, hostOrigin);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: host origin is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  nsTArray<size_t> region;
+  rv = WebCL_variantToRegion (cx, aRegion, region);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: region is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+
+  void* data = 0;
+  size_t length = 0;
+  nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
+  rv = variantTypedArrayToData (cx, aData, &data, &length, getter_AddRefs(holder));
+  NS_ENSURE_SUCCESS (rv, WEBCL_XPCOM_ERROR);
+
+
+  // Check that data object has enough data to be written.
+  // hostOrigin: (x, y, z)  region: (width, height, depth)
+  size_t reqSize = 0;
+  size_t rowPitch = aHostRowPitch != 0 ? aHostRowPitch : (hostOrigin[0] + region[0]);
+  if (region[2] > 1)
+  {
+    // 3D region
+    size_t slicePitch = aHostSlicePitch != 0 ? aHostSlicePitch : rowPitch * (hostOrigin[1] + region[1]);
+    reqSize = (hostOrigin[2] + region[2]) * slicePitch;
+  }
+  else
+  {
+    // 2D region
+    reqSize = (hostOrigin[1] + region[1]) * rowPitch;
+  }
+  if (reqSize > length)
+  {
+    D_LOG (LOG_LEVEL_ERROR,
+           "Data buffer too small for region. "
+           "(buffer size: %u, required: %u)", length, reqSize);
+    WebCL_reportJSError (cx, "%s: Data buffer too small for region.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+
+  // Event wait list
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventWaitList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> eventList;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         eventList);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  cl_event event;
+  cl_int err = mWrapper->enqueueWriteBufferRect (mInternal, buffer->getInternal(),
+                                                 aBlockingWrite,
+                                                 bufOrigin.Elements(),
+                                                 hostOrigin.Elements(),
+                                                 region.Elements(),
+                                                 aBufferRowPitch, aBufferSlicePitch,
+                                                 aHostRowPitch, aHostSlicePitch,
+                                                 data, eventList, &event);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  // Holder for async operations, see EnqueueWriteBuffer for details
+  if (!aBlockingWrite)
+  {
+    NS_ADDREF (holder);
+    mWrapper->retainEvent (event);
+    void* userData = packBufferDataHolderUnrefCbUserData (mWrapper, holder);
+    if (userData)
+    {
+      NS_ADDREF (mWrapper);
+
+      err = mWrapper->setEventCallback (event, CL_COMPLETE, bufferDataHolderUnrefCb,
+                                        userData);
+      if (mWrapper->status() != WebCL_LibCLWrapper::SUCCESS || CL_FAILED (err))
+      {
+        D_LOG (LOG_LEVEL_ERROR, "setEventCallback failed with error %d.", err);
+        NS_RELEASE (holder);
+        mWrapper->releaseEvent (event);
+      }
+    }
+    else
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to pack user data for event cb: "
+      "Memory allocation failure?");
+      NS_RELEASE (holder);
+      mWrapper->releaseEvent (event);
+    }
+  }
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLEvent enqueueReadBufferRect (in nsISupports aBuffer, in boolean aBlockingRead, in nsIVariant aBufferOrigin, in nsIVariant aHostOrigin, in nsIVariant aRegion, in T_WebCLSize aBufferRowPitch, in T_WebCLSize aBufferSlicePitch, in T_WebCLSize aHostRowPitch, in T_WebCLSize aHostSlicePitch, in nsIVariant aData, [optional] in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueReadBufferRect(nsISupports *aBuffer, bool aBlockingRead, nsIVariant *aBufferOrigin, nsIVariant *aHostOrigin, nsIVariant *aRegion, T_WebCLSize aBufferRowPitch, T_WebCLSize aBufferSlicePitch, T_WebCLSize aHostRowPitch, T_WebCLSize aHostSlicePitch, nsIVariant *aData, nsIVariant *aEventWaitList, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aBuffer);
+  NS_ENSURE_ARG_POINTER (aBufferOrigin);
+  NS_ENSURE_ARG_POINTER (aHostOrigin);
+  NS_ENSURE_ARG_POINTER (aRegion);
+  NS_ENSURE_ARG_POINTER (aData);
+  NS_ENSURE_ARG_POINTER (aEventWaitList);
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsCOMPtr<WebCLMemoryObject> buffer = do_QueryInterface (aBuffer, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  nsTArray<size_t> bufOrigin;
+  rv = WEBCL_variantToOrigin (cx, aBufferOrigin, bufOrigin);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: buffer origin is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  nsTArray<size_t> hostOrigin;
+  rv = WEBCL_variantToOrigin (cx, aHostOrigin, hostOrigin);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: host origin is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  nsTArray<size_t> region;
+  rv = WebCL_variantToRegion (cx, aRegion, region);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: region is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+
+  void* data = 0;
+  size_t length = 0;
+  nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
+  rv = variantTypedArrayToData (cx, aData, &data, &length, getter_AddRefs(holder));
+  NS_ENSURE_SUCCESS (rv, WEBCL_XPCOM_ERROR);
+
+
+  // Check that data object has enough data to be written.
+  // hostOrigin: (x, y, z)  region: (width, height, depth)
+  size_t reqSize = 0;
+  size_t rowPitch = aHostRowPitch != 0 ? aHostRowPitch : (hostOrigin[0] + region[0]);
+  if (region[2] > 1)
+  {
+    // 3D region
+    size_t slicePitch = aHostSlicePitch != 0 ? aHostSlicePitch : rowPitch * (hostOrigin[1] + region[1]);
+    reqSize = (hostOrigin[2] + region[2]) * slicePitch;
+  }
+  else
+  {
+    // 2D region
+    reqSize = (hostOrigin[1] + region[1]) * rowPitch;
+  }
+  if (reqSize > length)
+  {
+    D_LOG (LOG_LEVEL_ERROR,
+           "Data buffer too small for region. "
+           "(buffer size: %u, required: %u)", length, reqSize);
+    WebCL_reportJSError (cx, "%s: Data buffer too small for region.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+
+  // Event wait list
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventWaitList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> eventList;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         eventList);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  cl_event event;
+  cl_int err = mWrapper->enqueueReadBufferRect (mInternal, buffer->getInternal(),
+                                                aBlockingRead,
+                                                bufOrigin.Elements(),
+                                                hostOrigin.Elements(),
+                                                region.Elements(),
+                                                aBufferRowPitch, aBufferSlicePitch,
+                                                aHostRowPitch, aHostSlicePitch,
+                                                data, eventList, &event);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  // Holder for async operations, see EnqueueWriteBuffer for details
+  if (!aBlockingRead)
+  {
+    NS_ADDREF (holder);
+    mWrapper->retainEvent (event);
+    void* userData = packBufferDataHolderUnrefCbUserData (mWrapper, holder);
+    if (userData)
+    {
+      NS_ADDREF (mWrapper);
+
+      err = mWrapper->setEventCallback (event, CL_COMPLETE, bufferDataHolderUnrefCb,
+                                        userData);
+      if (mWrapper->status() != WebCL_LibCLWrapper::SUCCESS || CL_FAILED (err))
+      {
+        D_LOG (LOG_LEVEL_ERROR, "setEventCallback failed with error %d.", err);
+        NS_RELEASE (holder);
+        mWrapper->releaseEvent (event);
+      }
+    }
+    else
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to pack user data for event cb: "
+      "Memory allocation failure?");
+      NS_RELEASE (holder);
+      mWrapper->releaseEvent (event);
+    }
+  }
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLEvent enqueueWriteImage (in nsISupports aImage, in boolean aBlockingWrite, in nsIVariant aOrigin, in nsIVariant aRegion, in T_WebCLSize aInputRowPitch, in T_WebCLSize aInputSlicePitch, in nsIVariant aData, [optional] in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueWriteImage(nsISupports *aImage, bool aBlockingWrite, nsIVariant *aOrigin, nsIVariant *aRegion, T_WebCLSize aInputRowPitch, T_WebCLSize aInputSlicePitch, nsIVariant *aData, nsIVariant *aEventWaitList, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aImage);
+  NS_ENSURE_ARG_POINTER (aOrigin);
+  NS_ENSURE_ARG_POINTER (aRegion);
+  NS_ENSURE_ARG_POINTER (aData);
+  NS_ENSURE_ARG_POINTER (aEventWaitList);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsCOMPtr<WebCLMemoryObject> image = do_QueryInterface (aImage, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  nsTArray<size_t> origin;
+  rv = WEBCL_variantToOrigin (cx, aOrigin, origin);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: origin is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  nsTArray<size_t> region;
+  rv = WebCL_variantToRegion (cx, aRegion, region);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: region is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+
+  void* data = 0;
+  size_t length = 0;
+  nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
+  rv = variantTypedArrayToData (cx, aData, &data, &length, getter_AddRefs(holder));
+  NS_ENSURE_SUCCESS (rv, WEBCL_XPCOM_ERROR);
+
+
+  // Make sure the array buffer is large enough for the requested
+  // image data.
+  size_t imgElemSize = 0;
+  cl_int err = mWrapper->getImageInfo (image->getInternal(),
+                                         CL_IMAGE_ELEMENT_SIZE, imgElemSize);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to get image element size. (error %d)", err);
+    WebCL_reportJSError (cx, "%s: Failed to get image element size, error %d.",
+                         __FUNCTION__, err);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  // If aInputRowPitch or aInputSlicePitch are zero, calculate appropriate values.
+  size_t reqSize = 0;
+  size_t rowPitch = aInputRowPitch != 0 ? aInputRowPitch : region[0] * imgElemSize;
+  if (region[2] > 1)
+  {
+    // 3D image
+    size_t slicePitch = aInputSlicePitch != 0 ? aInputSlicePitch : rowPitch * region[1];
+    reqSize = region[2] * slicePitch;
+  }
+  else
+  {
+    // 2D image
+    reqSize = region[1] * rowPitch;
+  }
+  if (reqSize > length)
+  {
+    D_LOG (LOG_LEVEL_ERROR,
+           "Data buffer too small for region. "
+           "(buffer size: %u, required: %u)", length, reqSize);
+    WebCL_reportJSError (cx, "%s: Data buffer too small for region.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+
+  // Event wait list
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventWaitList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> eventList;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         eventList);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  cl_event event;
+  err = mWrapper->enqueueWriteImage (mInternal, image->getInternal(),
+                                     aBlockingWrite,
+                                     origin.Elements(),
+                                     region.Elements(),
+                                     aInputRowPitch, aInputSlicePitch,
+                                     data, eventList, &event);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  // Holder for async operations, see EnqueueWriteBuffer for details
+  if (!aBlockingWrite)
+  {
+    NS_ADDREF (holder);
+    mWrapper->retainEvent (event);
+    void* userData = packBufferDataHolderUnrefCbUserData (mWrapper, holder);
+    if (userData)
+    {
+      NS_ADDREF (mWrapper);
+
+      err = mWrapper->setEventCallback (event, CL_COMPLETE, bufferDataHolderUnrefCb,
+                                        userData);
+      if (mWrapper->status() != WebCL_LibCLWrapper::SUCCESS || CL_FAILED (err))
+      {
+        D_LOG (LOG_LEVEL_ERROR, "setEventCallback failed with error %d.", err);
+        NS_RELEASE (holder);
+        mWrapper->releaseEvent (event);
+      }
+    }
+    else
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to pack user data for event cb: "
+      "Memory allocation failure?");
+      NS_RELEASE (holder);
+      mWrapper->releaseEvent (event);
+    }
+  }
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLEvent enqueueReadImage (in nsISupports aImage, in boolean aBlockingRead, in nsIVariant aOrigin, in nsIVariant aRegion, in T_WebCLSize aRowPitch, in T_WebCLSize aSlicePitch, in nsIVariant aData, [optional] in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueReadImage(nsISupports *aImage, bool aBlockingRead, nsIVariant *aOrigin, nsIVariant *aRegion, T_WebCLSize aRowPitch, T_WebCLSize aSlicePitch, nsIVariant *aData, nsIVariant *aEventWaitList, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aImage);
+  NS_ENSURE_ARG_POINTER (aOrigin);
+  NS_ENSURE_ARG_POINTER (aRegion);
+  NS_ENSURE_ARG_POINTER (aData);
+  NS_ENSURE_ARG_POINTER (aEventWaitList);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsCOMPtr<WebCLMemoryObject> image = do_QueryInterface (aImage, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  nsTArray<size_t> origin;
+  rv = WEBCL_variantToOrigin (cx, aOrigin, origin);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: origin is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  nsTArray<size_t> region;
+  rv = WebCL_variantToRegion (cx, aRegion, region);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: region is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+
+  void* data = 0;
+  size_t length = 0;
+  nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
+  rv = variantTypedArrayToData (cx, aData, &data, &length, getter_AddRefs(holder));
+  NS_ENSURE_SUCCESS (rv, WEBCL_XPCOM_ERROR);
+
+
+  // Make sure the array buffer is large enough for the requested
+  // image data.
+  size_t imgElemSize = 0;
+  cl_int err = mWrapper->getImageInfo (image->getInternal(),
+                                         CL_IMAGE_ELEMENT_SIZE, imgElemSize);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to get image element size. (error %d)", err);
+    WebCL_reportJSError (cx, "%s: Failed to get image element size, error %d.",
+                         __FUNCTION__, err);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  // If aRowPitch or aSlicePitch are zero, calculate appropriate values.
+  size_t reqSize = 0;
+  size_t rowPitch = aRowPitch != 0 ? aRowPitch : region[0] * imgElemSize;
+  if (region[2] > 1)
+  {
+    // 3D image
+    size_t slicePitch = aSlicePitch != 0 ? aSlicePitch : rowPitch * region[1];
+    reqSize = region[2] * slicePitch;
+  }
+  else
+  {
+    // 2D image
+    reqSize = region[1] * rowPitch;
+  }
+  if (reqSize > length)
+  {
+    D_LOG (LOG_LEVEL_ERROR,
+           "Data buffer too small for region. "
+           "(buffer size: %u, required: %u)", length, reqSize);
+    WebCL_reportJSError (cx, "%s: Data buffer too small for region.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+
+  // Event wait list
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventWaitList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> eventList;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         eventList);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  cl_event event;
+  err = mWrapper->enqueueReadImage (mInternal, image->getInternal(),
+                                    aBlockingRead,
+                                    origin.Elements(),
+                                    region.Elements(),
+                                    aRowPitch, aSlicePitch,
+                                    data, eventList, &event);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  // Holder for async operations, see EnqueueWriteBuffer for details
+  if (!aBlockingRead)
+  {
+    NS_ADDREF (holder);
+    mWrapper->retainEvent (event);
+    void* userData = packBufferDataHolderUnrefCbUserData (mWrapper, holder);
+    if (userData)
+    {
+      NS_ADDREF (mWrapper);
+
+      err = mWrapper->setEventCallback (event, CL_COMPLETE, bufferDataHolderUnrefCb,
+                                        userData);
+      if (mWrapper->status() != WebCL_LibCLWrapper::SUCCESS || CL_FAILED (err))
+      {
+        D_LOG (LOG_LEVEL_ERROR, "setEventCallback failed with error %d.", err);
+        NS_RELEASE (holder);
+        mWrapper->releaseEvent (event);
+      }
+    }
+    else
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to pack user data for event cb: "
+      "Memory allocation failure?");
+      NS_RELEASE (holder);
+      mWrapper->releaseEvent (event);
+    }
+  }
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLEvent enqueueCopyImage (in nsISupports aSrcImage, in nsISupports aDstImage, in nsIVariant aSrcOrigin, in nsIVariant aDstOrigin, in nsIVariant aRegion, [optional] in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueCopyImage(nsISupports *aSrcImage, nsISupports *aDstImage, nsIVariant *aSrcOrigin, nsIVariant *aDstOrigin, nsIVariant *aRegion, nsIVariant *aEventWaitList, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aSrcImage);
+  NS_ENSURE_ARG_POINTER (aDstImage);
+  NS_ENSURE_ARG_POINTER (aSrcOrigin);
+  NS_ENSURE_ARG_POINTER (aDstOrigin);
+  NS_ENSURE_ARG_POINTER (aRegion);
+  NS_ENSURE_ARG_POINTER (aEventWaitList);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsCOMPtr<WebCLMemoryObject> srcImage = do_QueryInterface (aSrcImage, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsCOMPtr<WebCLMemoryObject> dstImage = do_QueryInterface (aDstImage, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  nsTArray<size_t> srcOrigin;
+  rv = WEBCL_variantToOrigin (cx, aSrcOrigin, srcOrigin);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: source origin is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  nsTArray<size_t> dstOrigin;
+  rv = WEBCL_variantToOrigin (cx, aDstOrigin, dstOrigin);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: destination origin is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  nsTArray<size_t> region;
+  rv = WebCL_variantToRegion (cx, aRegion, region);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: region is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+
+  // Event wait list
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventWaitList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> eventList;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         eventList);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  cl_event event;
+  cl_int err = mWrapper->enqueueCopyImage (mInternal,
+                                           srcImage->getInternal(),
+                                           dstImage->getInternal(),
+                                           srcOrigin.Elements(),
+                                           dstOrigin.Elements(),
+                                           region.Elements(), eventList, &event);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLEvent enqueueCopyImageToBuffer (in nsISupports aSrcImage, in nsISupports aDstBuffer, in nsIVariant aSrcOrigin, in nsIVariant aRegion, in T_WebCLSize aDstOffset, [optional] in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueCopyImageToBuffer(nsISupports *aSrcImage, nsISupports *aDstBuffer, nsIVariant *aSrcOrigin, nsIVariant *aRegion, T_WebCLSize aDstOffset, nsIVariant *aEventWaitList, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aSrcImage);
+  NS_ENSURE_ARG_POINTER (aDstBuffer);
+  NS_ENSURE_ARG_POINTER (aSrcOrigin);
+  NS_ENSURE_ARG_POINTER (aRegion);
+  NS_ENSURE_ARG_POINTER (aEventWaitList);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsCOMPtr<WebCLMemoryObject> srcImage = do_QueryInterface (aSrcImage, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsCOMPtr<WebCLMemoryObject> dstBuffer = do_QueryInterface (aDstBuffer, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  nsTArray<size_t> srcOrigin;
+  rv = WEBCL_variantToOrigin (cx, aSrcOrigin, srcOrigin);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: source origin is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  nsTArray<size_t> region;
+  rv = WebCL_variantToRegion (cx, aRegion, region);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: region is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+
+  // Event wait list
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventWaitList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> eventList;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         eventList);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  cl_event event;
+  cl_int err = mWrapper->enqueueCopyImageToBuffer (mInternal,
+                                                   srcImage->getInternal(),
+                                                   dstBuffer->getInternal(),
+                                                   srcOrigin.Elements(),
+                                                   region.Elements(),
+                                                   aDstOffset, eventList, &event);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLEvent enqueueCopyBufferToImage (in nsISupports aSrcBuffer, in nsISupports aDstImage, in T_WebCLSize aSrcOffset, in nsIVariant aDstOrigin, in nsIVariant aRegion, [optional] in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueCopyBufferToImage(nsISupports *aSrcBuffer, nsISupports *aDstImage, T_WebCLSize aSrcOffset, nsIVariant *aDstOrigin, nsIVariant *aRegion, nsIVariant *aEventWaitList, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aSrcBuffer);
+  NS_ENSURE_ARG_POINTER (aDstImage);
+  NS_ENSURE_ARG_POINTER (aDstOrigin);
+  NS_ENSURE_ARG_POINTER (aRegion);
+  NS_ENSURE_ARG_POINTER (aEventWaitList);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsCOMPtr<WebCLMemoryObject> srcBuffer = do_QueryInterface (aSrcBuffer, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsCOMPtr<WebCLMemoryObject> dstImage = do_QueryInterface (aDstImage, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  nsTArray<size_t> dstOrigin;
+  rv = WEBCL_variantToOrigin (cx, aDstOrigin, dstOrigin);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: destination origin is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  nsTArray<size_t> region;
+  rv = WebCL_variantToRegion (cx, aRegion, region);
+  if (NS_FAILED (rv))
+  {
+    WebCL_reportJSError (cx, "%s: region is not an array of 3 integers.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+
+  // Event wait list
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventWaitList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> eventList;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         eventList);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+
+  cl_event event;
+  cl_int err = mWrapper->enqueueCopyBufferToImage (mInternal,
+                                                   srcBuffer->getInternal(),
+                                                   dstImage->getInternal(),
+                                                   aSrcOffset,
+                                                   dstOrigin.Elements(),
+                                                   region.Elements(),
+                                                   eventList, &event);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLEvent enqueueMapBuffer (in nsISupports aBuffer, in boolean aBlockingMap, in T_WebCLMapFlags aMapFlags, in T_WebCLSize aOffset, in T_WebCLSize aSize, in nsIVariant aEventWaitList, in nsIVariant aData); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueMapBuffer(nsISupports *aBuffer, bool aBlockingMap, T_WebCLMapFlags aMapFlags, T_WebCLSize aOffset, T_WebCLSize aSize, nsIVariant *aEventWaitList, nsIVariant *aData, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  // TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  // TODO: How do we map buffers to typed arrays?
+  // TODO: One option would be to setup an event callback and create a fake
+  // TODO: arraybuffer on completion, providing access to the mapped region.
+  // TODO: Memory management would still be a huge issue and unmap might
+  // TODO: open up a vulnerability.
+  // TODO: The safest option may be to remove buffer/image mapping from WebCL.
+  // TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  WebCL_reportJSError (cx, "enqueueMapBuffer is currently not supported by this WebCL implementation.");
+  return WEBCL_XPCOM_ERROR;
+}
+
+
+/* IWebCLEvent enqueueMapImage (in nsISupports aImage, in boolean aBlockingMap, in T_WebCLMapFlags aMapFlags, in nsIVariant aOrigin, in nsIVariant aRegion, in nsIVariant aEventWaitList, in nsIVariant aData); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueMapImage(nsISupports *aImage, bool aBlockingMap, T_WebCLMapFlags aMapFlags, nsIVariant *aOrigin, nsIVariant *aRegion, nsIVariant *aEventWaitList, nsIVariant *aData, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  // NOTE: see EnqueueMapBuffer
+  WebCL_reportJSError (cx, "enqueueMapImage is currently not supported by this WebCL implementation.");
+  return WEBCL_XPCOM_ERROR;
+}
+
+
+/* IWebCLEvent enqueueUnmapMemObject (in nsISupports aMemObject, in nsIVariant aMappedData, [optional] in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueUnmapMemObject(nsISupports *aMemObject, nsIVariant *aMappedData, nsIVariant *aEventWaitList, JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  // NOTE: see EnqueueMapBuffer
+  WebCL_reportJSError (cx, "enqueueUnmapMemObject is currently not supported by this WebCL implementation.");
+  return WEBCL_XPCOM_ERROR;
+}
+
+
+/* IWebCLEvent enqueueMarker (); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueMarker(JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+  nsresult rv;
+
+  cl_event event;
+  cl_int err = mWrapper->enqueueMarker (mInternal, &event);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* void enqueueWaitForEvents (in nsIVariant aEventWaitList); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueWaitForEvents(nsIVariant *aEventWaitList, JSContext *cx)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aEventWaitList);
+  NS_ENSURE_ARG_POINTER (cx);
+  nsresult rv;
+
+  nsTArray<nsIVariant*> eventVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aEventWaitList, eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_event> eventList;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLEvent, cl_event> (eventVariants,
+                                                                         eventList);
+  WebCL_releaseVariantVector (eventVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  cl_int err = mWrapper->enqueueWaitForEvents (mInternal, eventList);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  return NS_OK;
+}
+
+
+/* void enqueueBarrier (); */
+NS_IMETHODIMP WebCLCommandQueue::EnqueueBarrier(JSContext *cx)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+
+  cl_int err = mWrapper->enqueueBarrier (mInternal);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  return NS_OK;
+}
+
+
+/* void flush (); */
+NS_IMETHODIMP WebCLCommandQueue::Flush(JSContext *cx)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+
+  cl_int err = mWrapper->flush (mInternal);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  return NS_OK;
+}
+
+
+/* void finish (); */
+NS_IMETHODIMP WebCLCommandQueue::Finish(JSContext *cx)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+
+  cl_int err = mWrapper->finish (mInternal);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  return NS_OK;
+}
+
+
+/* void releaseCLResources (); */
+NS_IMETHODIMP WebCLCommandQueue::ReleaseCLResources ()
+{
+  D_METHOD_START;
+  if (mWrapper && mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (CL_FAILED (mWrapper->releaseCommandQueue (mInternal)))
+      D_LOG (LOG_LEVEL_WARNING, "Failed to release CL resources.");
+    mInternal = 0;
+  }
+  mWrapper = 0;
+  return NS_OK;
+}
\ No newline at end of file
diff -r 450143d2d810 browser/components/webcl/src/WebCLCommandQueue.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLCommandQueue.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,69 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCLCOMMANDQUEUE_H_
+#define _WEBCLCOMMANDQUEUE_H_
+
+#include "WebCLCommon.h"
+#include "IWebCLCommandQueue.h" // Generated from IWebCLCommandQueue.idl
+#include "instance_registry.h"
+
+#include <CL/opencl.h>
+
+
+#define WEBCL_COMMANDQUEUE_CLASSNAME "WebCLCommandQueue"
+#define WEBCL_COMMANDQUEUE_CID { 0x751b06c0, 0xcac3, 0x4123, { 0x87, 0xae, 0x2b, 0x8c, 0x22, 0x83, 0x2d, 0x52 } }
+#define WEBCL_COMMANDQUEUE_CONTRACTID "@webcl.nokiaresearch.com/WebCLCommandQueue;1"
+
+/** Implements IWebCLCommandQueue interface. */
+class WebCLCommandQueue : public IWebCLCommandQueue, public WebCLCommon
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISECURITYCHECKEDCOMPONENT
+  NS_DECL_IWEBCLCOMMANDQUEUE
+
+  static nsresult getInstance (cl_command_queue aInternal, WebCLCommandQueue** aResultOut,
+                               WebCL_LibCLWrapper* aLibWrapper = 0);
+
+  WebCLCommandQueue ();
+  cl_command_queue getInternal () { return mInternal; }
+
+protected:
+  int getTypeForInfoName (int aName);
+
+private:
+  static InstanceRegistry<cl_command_queue, WebCLCommandQueue*> instanceRegistry;
+
+  ~WebCLCommandQueue ();
+
+  cl_command_queue mInternal;
+};
+
+#endif //_WEBCLCOMMANDQUEUE_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCLCommon.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLCommon.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,64 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCLCommon.h"
+#include "WebCL_clwrapper.h"
+
+// Prevent error C2371 on MS Visual C++ 10 compiler.
+#if _MSC_VER >= 1000
+// Let jsapi know that it doesn't need to provide C99 exact types itself.
+# define JS_HAVE_STDINT_H 1
+#endif
+
+
+// WebCLCommon
+
+WebCLCommon::WebCLCommon ()
+  : mWrapper(0)
+{
+  D_METHOD_START;
+}
+
+
+WebCLCommon::~WebCLCommon ()
+{
+  D_METHOD_START;
+}
+
+
+void WebCLCommon::setWrapper (WebCL_LibCLWrapper* aWrapper)
+{
+  mWrapper = aWrapper;
+}
+
+
+WebCL_LibCLWrapper* WebCLCommon::getWrapper ()
+{
+  return mWrapper;
+}
diff -r 450143d2d810 browser/components/webcl/src/WebCLCommon.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLCommon.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,250 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+
+#ifndef _WEBCLCOMMON_H_
+#define _WEBCLCOMMON_H_
+
+#define __STDC_LIMIT_MACROS
+
+#include "WebCLLogger.h"
+
+#include "xpcom-config.h"
+#include "nsCRT.h"  //NS_strdup
+#include "nsCOMPtr.h"
+
+
+// Version number fallbacks. Actual values should come from Makefiles but if
+// that is not the case we can set some "legal" values here.
+#ifndef VERSION_MAJOR
+#  define VERSION_MAJOR 0
+#endif
+#ifndef VERSION_MINOR
+#  define VERSION_MINOR 0
+#endif
+
+
+/** \fn VALIDATE_ARG_WITH_ERROR
+ * Argument validation macro.
+ * This macro simplifies function argument validation. If \c test
+ * fails the function will return with evaluated value of the
+ * variadic argument ... as the return value.
+ * \param argName Name of the argument being tested (without quotes!)
+ * \param test The actual test, e.g. aNumber > 3 .
+ * \param statusPtr A pointer to which the error code is stored on failure,
+ *  or null value to disable, e.g. an out parameter.
+ * \param errNum The error code that is written through statusPtr on failure.
+ * \param ... The function return value.
+ */
+#ifdef WIN32
+# define VALIDATE_ARG_WITH_ERROR(argName, test, statusPtr, errNum, ...) do{ \
+  if ( !(test)) { \
+    if (statusPtr) *statusPtr = errNum; \
+    D_LOG (LOG_LEVEL_ERROR, "Invalid argument " #argName ": failed test \"" #test "\"."); \
+    return (__VA_ARGS__); \
+  } \
+}while(0)
+#else
+# define VALIDATE_ARG_WITH_ERROR(argName, test, statusPtr, errNum, rv...) do{ \
+  if ( !(test)) { \
+    if (statusPtr) *statusPtr = errNum; \
+    D_LOG (LOG_LEVEL_ERROR, "Invalid argument " #argName ": failed test \"" #test "\"."); \
+    return (rv); \
+  } \
+}while(0)
+#endif
+
+
+/** \fn VALIDATE_ARG
+ * Argument validation macro.
+ * This macro simplifies function argument validation. If \c test
+ * fails the function will return with evaluated value of the
+ * variadic argument ... as the return value.
+ * \param argName Name of the argument being tested (without quotes!)
+ * \param test The actual test, e.g. aNumber > 3 .
+ * \param statusPtr If non-null, error code CL_INVALID_ARG_VALUE is written
+ *  through this pointer.
+ * \param ... The function return value.
+ */
+#ifdef WIN32
+# define VALIDATE_ARG(argName, test, statusPtr, ...) \
+  VALIDATE_ARG_WITH_ERROR (argName, test, statusPtr, CL_INVALID_ARG_VALUE, __VA_ARGS__)
+#else
+# define VALIDATE_ARG(argName, test, statusPtr, rv...) \
+  VALIDATE_ARG_WITH_ERROR (argName, test, statusPtr, CL_INVALID_ARG_VALUE, rv)
+#endif
+
+
+/** \fn VALIDATE_ARG_POINTER_WITH_ERROR
+ * Pointer argument validation macro.
+ * This macro simplifies function argument validation. If \c ptr
+ * equals to null the function will return with evaluated value of the
+ * variadic argument ... as the return value.
+ * \param ptr The argument being tested.
+ * \param statusPtr A pointer to which the error code is stored on failure,
+ *  or null value to disable, e.g. an out parameter.
+ * \param errNum The error code that is written through statusPtr on failure.
+ * \param ... The function return value.
+ */
+#ifdef WIN32
+# define VALIDATE_ARG_POINTER_WITH_ERROR(ptr, statusPtr, errNum, ...) do{ \
+  if (ptr == 0) { \
+    void* tmp = statusPtr; /* Avoid gcc warning.. */ \
+    if (tmp) *statusPtr = errNum; \
+    D_LOG (LOG_LEVEL_ERROR, "Invalid argument " #ptr ": null pointer."); \
+    return (__VA_ARGS__); \
+  } \
+}while(0)
+#else
+# define VALIDATE_ARG_POINTER_WITH_ERROR(ptr, statusPtr, errNum, rv...) do{ \
+  if (ptr == 0) { \
+    void* tmp = statusPtr; /* Avoid gcc warning.. */ \
+    if (tmp) *statusPtr = errNum; \
+    D_LOG (LOG_LEVEL_ERROR, "Invalid argument " #ptr ": null pointer."); \
+    return (rv); \
+  } \
+}while(0)
+#endif
+
+
+/** \fn VALIDATE_ARG_POINTER
+ * Pointer argument validation macro.
+ * This macro simplifies function argument validation. If \c ptr
+ * equals to null the function will return with evaluated value of the
+ * variadic argument ... as the return value.
+ * \param ptr The argument being tested.
+ * \param statusPtr If non-null, error code CL_INVALID_ARG_VALUE is written
+ *  through this pointer.
+ * \param ... The function return value.
+ */
+#ifdef WIN32
+# define VALIDATE_ARG_POINTER(ptr, statusPtr, ...) \
+  VALIDATE_ARG_POINTER_WITH_ERROR (ptr, statusPtr, CL_INVALID_ARG_VALUE, __VA_ARGS__)
+#else
+# define VALIDATE_ARG_POINTER(ptr, statusPtr, rv...) \
+  VALIDATE_ARG_POINTER_WITH_ERROR (ptr, statusPtr, CL_INVALID_ARG_VALUE, rv)
+#endif
+
+
+#define ENSURE_LIB_WRAPPER_SUCCESS(lib) do{ \
+  if (lib->status() != WebCL_LibCLWrapper::SUCCESS) { \
+    /* TODO: report detailed error to user */ \
+    return NS_ERROR_NOT_IMPLEMENTED; \
+  } }while(0)
+
+
+#define ENSURE_CL_OP_SUCCESS(err) do{ \
+  if (CL_FAILED (err)) { \
+    WebCL_reportJSError (cx, "%s Failed with error %d.", __FUNCTION__, err); \
+    return WEBCL_XPCOM_ERROR; /* NS_ERROR_FAILURE; */ \
+  } }while(0)
+
+
+//==============================================================================
+
+class WebCL_LibCLWrapper;
+
+class WebCLCommon {
+public:
+  WebCLCommon ();
+  virtual ~WebCLCommon ();
+
+  void setInternal (void* aObject);
+  void setWrapper (WebCL_LibCLWrapper* aWrapper);
+  WebCL_LibCLWrapper* getWrapper ();
+
+protected:
+  nsCOMPtr<WebCL_LibCLWrapper> mWrapper;
+
+private:
+  // Prevent copying and assignment
+  WebCLCommon (WebCLCommon const&);
+  WebCLCommon& operator= (WebCLCommon const&);
+};
+
+
+
+//==============================================================================
+
+
+
+#define C_COM_SECURITY_ALL_ACCESS  "allAccess"
+#define C_COM_SECURITY_NO_ACCESS   "noAccess"
+
+
+// These macros are used for implementing the nsSecurityCheckedComponent interface
+// that is shared by all WebCL classes
+#define WEBCL_SECURITY_CHECKED_CANCREATEWRAPPER_IMPL(cname) \
+NS_IMETHODIMP \
+cname::CanCreateWrapper (const nsIID* aIID, \
+char** _retval) { \
+D_METHOD_START; \
+*_retval = NS_strdup (C_COM_SECURITY_ALL_ACCESS); \
+return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; \
+}
+
+#define WEBCL_SECURITY_CHECKED_CANCALLMETHOD_IMPL(cname) \
+NS_IMETHODIMP \
+cname::CanCallMethod (const nsIID* aIID, const PRUnichar* aMethodName, \
+char** _retval) { \
+D_METHOD_START; \
+NS_ENSURE_TRUE (_retval, NS_ERROR_NULL_POINTER); \
+*_retval = NS_strdup (C_COM_SECURITY_ALL_ACCESS); \
+return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; \
+}
+
+#define WEBCL_SECURITY_CHECKED_CANGETPROPERTY_IMPL(cname) \
+NS_IMETHODIMP \
+cname::CanGetProperty (const nsIID* aIID, const PRUnichar* aPropertyName, \
+char** _retval) { \
+D_METHOD_START; \
+NS_ENSURE_TRUE (_retval, NS_ERROR_NULL_POINTER); \
+*_retval = NS_strdup (C_COM_SECURITY_ALL_ACCESS); \
+return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; \
+}
+
+#define WEBCL_SECURITY_CHECKED_CANSETPROPERTY_IMPL(cname) \
+NS_IMETHODIMP \
+cname::CanSetProperty (const nsIID* aIID, const PRUnichar* aPropertyName, \
+char** _retval) { \
+D_METHOD_START; \
+NS_ENSURE_TRUE (_retval, NS_ERROR_NULL_POINTER); \
+*_retval = NS_strdup (C_COM_SECURITY_NO_ACCESS); \
+return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; \
+}
+
+
+#define WEBCL_SECURITY_CHECKED_IMPL(cname) \
+WEBCL_SECURITY_CHECKED_CANCREATEWRAPPER_IMPL (cname) \
+WEBCL_SECURITY_CHECKED_CANCALLMETHOD_IMPL (cname) \
+WEBCL_SECURITY_CHECKED_CANGETPROPERTY_IMPL (cname) \
+WEBCL_SECURITY_CHECKED_CANSETPROPERTY_IMPL (cname)
+
+
+#endif /* _WEBCLCOMMON_H_ */
diff -r 450143d2d810 browser/components/webcl/src/WebCLContext.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLContext.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,359 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCLContext.h"
+#include "WebCLCommon.h"
+#include "WebCL_internal.h"
+#include "WebCL_clwrapper.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsISecurityCheckedComponent.h"
+
+
+NS_IMPL_ISUPPORTS2 (WebCLContext, IWebCLContext, nsISecurityCheckedComponent)
+WEBCL_SECURITY_CHECKED_IMPL (WebCLContext)
+
+
+/* static */
+InstanceRegistry<cl_context, WebCLContext*> WebCLContext::instanceRegistry;
+
+
+/* static */
+nsresult WebCLContext::getInstance (cl_context aInternal, WebCLContext** aResultOut,
+                                    WebCL_LibCLWrapper* aLibWrapper)
+{
+  nsresult rv = NS_OK;
+
+  WebCLContext* existing = 0;
+  if (instanceRegistry.findById (aInternal, &existing))
+  {
+    NS_IF_ADDREF (*aResultOut = existing);
+  }
+  else
+  {
+    nsCOMPtr<WebCLContext> obj = do_CreateInstance (WEBCL_CONTEXT_CONTRACTID, &rv);
+    if (NS_FAILED (rv))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to create instance. rv=%d.", rv);
+      return rv;
+    }
+
+    obj->setWrapper (aLibWrapper);
+    obj->mInternal = aInternal;
+
+    instanceRegistry.add (obj->mInternal, obj);
+
+    NS_IF_ADDREF (*aResultOut = obj);
+  }
+
+  return rv;
+}
+
+
+WebCLContext::WebCLContext()
+  : IWebCLContext(), WebCLCommon(),
+    mInternal(0)
+{
+  D_METHOD_START;
+}
+
+
+WebCLContext::~WebCLContext()
+{
+  D_METHOD_START;
+  if (mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (mWrapper)
+      mWrapper->releaseContext (mInternal);
+    mInternal = 0;
+  }
+}
+
+
+int WebCLContext::getTypeForInfoName (int aName) {
+  D_METHOD_START;
+  switch (aName)
+  {
+    case CL_CONTEXT_REFERENCE_COUNT: return types::UINT;
+    case CL_CONTEXT_NUM_DEVICES: return types::UINT;
+    case CL_CONTEXT_DEVICES: return types::DEVICE_V;
+    case CL_CONTEXT_PROPERTIES: return types::INT_V;
+    default: ;
+  }
+  return types::UNKNOWN;
+}
+
+
+/* nsIVariant getContextInfo (in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLContext::GetContextInfo(PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  WEBCL_GETINFO_MEDIATOR_SWITCH (aName, type, mWrapper, getContextInfo, mInternal,
+                                 variant, err, rv);
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
+
+
+/* IWebCLProgram createProgramWithSource (in string aSource); */
+NS_IMETHODIMP WebCLContext::CreateProgramWithSource(const char *aSource, JSContext *cx, IWebCLProgram **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aSource);
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  cl_int err = CL_SUCCESS;
+  cl_program program = mWrapper->createProgramWithSource (mInternal,
+                                                          nsCString(aSource), &err);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLProgram> xpcObj;
+  rv = WebCLProgram::getInstance (program, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLCommandQueue createCommandQueue (in IWebCLDevice aDevice, in T_WebCLCommandQueueProperties aProperties); */
+NS_IMETHODIMP WebCLContext::CreateCommandQueue(nsISupports *aDevice, T_WebCLCommandQueueProperties aProperties, JSContext *cx, IWebCLCommandQueue **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsCOMPtr<WebCLDevice> device (do_QueryInterface (aDevice, &rv));
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  cl_int err = CL_SUCCESS;
+  cl_command_queue cmd = mWrapper->createCommandQueue (mInternal, device->getInternal(),
+                                                       aProperties, &err);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLCommandQueue> xpcObj;
+  rv = WebCLCommandQueue::getInstance (cmd, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLMemoryObject createBuffer (in T_WebCLMemFlags aFlags, in T_WebCLSize aSize); */
+NS_IMETHODIMP WebCLContext::CreateBuffer(T_WebCLMemFlags aFlags, T_WebCLSize aSize, JSContext *cx, IWebCLMemoryObject **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  cl_int err = CL_SUCCESS;
+  cl_mem mem = mWrapper->createBuffer (mInternal, aFlags, aSize, 0, &err);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLMemoryObject> xpcObj;
+  rv = WebCLMemoryObject::getInstance (mem, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLMemoryObject createImage2D (in T_WebCLMemFlags aFlags, in nsIVariant aImageFormat, in T_WebCLSize aWidth, in T_WebCLSize aHeight, in T_WebCLSize aRowPitch); */
+NS_IMETHODIMP WebCLContext::CreateImage2D(T_WebCLMemFlags aFlags, nsIVariant *aImageFormat, T_WebCLSize aWidth, T_WebCLSize aHeight, T_WebCLSize aRowPitch, JSContext *cx, IWebCLMemoryObject **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  cl_image_format format;
+  rv = WebCL_variantToImageFormat (cx, aImageFormat, format);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  cl_int err = CL_SUCCESS;
+  cl_mem mem = mWrapper->createImage2D (mInternal, aFlags, &format,
+                                        aWidth, aHeight, aRowPitch, 0, &err);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLMemoryObject> xpcObj;
+  rv = WebCLMemoryObject::getInstance (mem, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLMemoryObject createImage3D (in T_WebCLMemFlags aFlags, in nsIVariant aImageFormat, in T_WebCLSize aWidth, in T_WebCLSize aHeight, in T_WebCLSize aDepth, in T_WebCLSize aRowPitch, in T_WebCLSize aSlicePitch); */
+NS_IMETHODIMP WebCLContext::CreateImage3D(T_WebCLMemFlags aFlags, nsIVariant *aImageFormat, T_WebCLSize aWidth, T_WebCLSize aHeight, T_WebCLSize aDepth, T_WebCLSize aRowPitch, T_WebCLSize aSlicePitch, JSContext *cx, IWebCLMemoryObject **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  cl_image_format format;
+  rv = WebCL_variantToImageFormat (cx, aImageFormat, format);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  cl_int err = CL_SUCCESS;
+  cl_mem mem = mWrapper->createImage3D (mInternal, aFlags, &format,
+                                        aWidth, aHeight, aDepth,
+                                        aRowPitch, aSlicePitch, 0, &err);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLMemoryObject> xpcObj;
+  rv = WebCLMemoryObject::getInstance (mem, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* IWebCLSampler createSampler (in boolean aNormalizedCoords, in T_WebCLAddressingMode aAddressingMode, in T_WebCLFilterMode aFilterMode); */
+NS_IMETHODIMP WebCLContext::CreateSampler(bool aNormalizedCoords, T_WebCLAddressingMode aAddressingMode, T_WebCLFilterMode aFilterMode, JSContext *cx, IWebCLSampler **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  cl_int err = CL_SUCCESS;
+  cl_sampler sampler = mWrapper->createSampler (mInternal, aNormalizedCoords,
+                                                aAddressingMode, aFilterMode, &err);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLSampler> xpcObj;
+  rv = WebCLSampler::getInstance (sampler, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* nsIVariant getSupportedImageFormats (in T_WebCLMemFlags aFlags, in T_WebCLMemObjectType aImageType); */
+NS_IMETHODIMP WebCLContext::GetSupportedImageFormats(T_WebCLMemFlags aFlags, T_WebCLMemObjectType aImageType, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsTArray<cl_image_format> imageFormats;
+  cl_int err = mWrapper->getSupportedImageFormats (mInternal, aFlags, aImageType,
+                                                   imageFormats);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<nsIVariant> value;
+  rv = WebCL_convertVectorToJSArrayInVariant (cx, imageFormats, getter_AddRefs (value),
+                                              mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = value);
+  return NS_OK;
+}
+
+
+/* IWebCLEvent createUserEvent (); */
+NS_IMETHODIMP WebCLContext::CreateUserEvent(JSContext *cx, IWebCLEvent **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  cl_int err = CL_SUCCESS;
+  cl_event event = mWrapper->createUserEvent (mInternal, &err);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLEvent> xpcObj;
+  rv = WebCLEvent::getInstance (event, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* void releaseCLResources (); */
+NS_IMETHODIMP WebCLContext::ReleaseCLResources ()
+{
+  D_METHOD_START;
+  if (mWrapper && mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (CL_FAILED (mWrapper->releaseContext (mInternal)))
+      D_LOG (LOG_LEVEL_WARNING, "Failed to release CL resources.");
+    mInternal = 0;
+  }
+  mWrapper = 0;
+  return NS_OK;
+}
diff -r 450143d2d810 browser/components/webcl/src/WebCLContext.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLContext.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,69 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCLCONTEXT_H_
+#define _WEBCLCONTEXT_H_
+
+#include "WebCLCommon.h"
+#include "IWebCLContext.h" // Generated from IWebCLContext.idl
+#include "instance_registry.h"
+
+#include <CL/opencl.h>
+
+
+#define WEBCL_CONTEXT_CLASSNAME "WebCLContext"
+#define WEBCL_CONTEXT_CID { 0x0e5fba5c, 0x091f, 0x40db, { 0xa6, 0xa9, 0x70, 0x0b, 0xa5, 0x03, 0x93, 0xd0 } }
+#define WEBCL_CONTEXT_CONTRACTID "@webcl.nokiaresearch.com/WebCLContext;1"
+
+/** Implements IWebCLContext interface. */
+class WebCLContext : public IWebCLContext, public WebCLCommon
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISECURITYCHECKEDCOMPONENT
+  NS_DECL_IWEBCLCONTEXT
+
+  static nsresult getInstance (cl_context aInternal, WebCLContext** aResultOut,
+                               WebCL_LibCLWrapper* aLibWrapper = 0);
+
+  WebCLContext ();
+  cl_context getInternal () { return mInternal; }
+
+protected:
+  int getTypeForInfoName (int aName);
+
+private:
+  static InstanceRegistry<cl_context, WebCLContext*> instanceRegistry;
+
+  ~WebCLContext ();
+
+  cl_context mInternal;
+};
+
+#endif //_WEBCLCONTEXT_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCLDevice.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLDevice.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,184 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCLDevice.h"
+#include "WebCLCommon.h"
+#include "WebCL_internal.h"
+#include "WebCL_clwrapper.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsISecurityCheckedComponent.h"
+
+
+NS_IMPL_ISUPPORTS2 (WebCLDevice, IWebCLDevice, nsISecurityCheckedComponent)
+WEBCL_SECURITY_CHECKED_IMPL (WebCLDevice)
+
+
+/* static */
+InstanceRegistry<cl_device_id, WebCLDevice*> WebCLDevice::instanceRegistry;
+
+
+/* static */
+nsresult WebCLDevice::getInstance (cl_device_id aInternal, WebCLDevice** aResultOut,
+                                   WebCL_LibCLWrapper* aLibWrapper)
+{
+  nsresult rv = NS_OK;
+
+  WebCLDevice* existing = 0;
+  if (instanceRegistry.findById (aInternal, &existing))
+  {
+    NS_IF_ADDREF (*aResultOut = existing);
+  }
+  else
+  {
+    nsCOMPtr<WebCLDevice> obj = do_CreateInstance (WEBCL_DEVICE_CONTRACTID, &rv);
+    if (NS_FAILED (rv))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to create instance. rv=%d.", rv);
+      return rv;
+    }
+
+    obj->setWrapper (aLibWrapper);
+    obj->mInternal = aInternal;
+
+    instanceRegistry.add (obj->mInternal, obj);
+
+    NS_IF_ADDREF (*aResultOut = obj);
+  }
+
+  return rv;
+}
+
+
+WebCLDevice::WebCLDevice()
+  : IWebCLDevice(), WebCLCommon(),
+    mInternal(0)
+{
+  D_METHOD_START;
+}
+
+
+WebCLDevice::~WebCLDevice()
+{
+  D_METHOD_START;
+  if (mInternal)
+    instanceRegistry.remove (mInternal);
+}
+
+
+int WebCLDevice::getTypeForInfoName (int aName)
+{
+  D_METHOD_START;
+  switch (aName)
+  {
+    case CL_DEVICE_ADDRESS_BITS: return types::UINT;
+    case CL_DEVICE_AVAILABLE: return types::BOOL;
+    case CL_DEVICE_COMPILER_AVAILABLE: return types::BOOL;
+    //case CL_DEVICE_DOUBLE_FP_CONFIG: return types::DEVICE_FP_CONFIG;
+    case CL_DEVICE_ENDIAN_LITTLE: return types::BOOL;
+    case CL_DEVICE_ERROR_CORRECTION_SUPPORT: return types::BOOL;
+    case CL_DEVICE_EXECUTION_CAPABILITIES: return types::DEVICE_EXEC_CAPABILITIES;
+    case CL_DEVICE_EXTENSIONS: return types::STRING;
+    case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE: return types::ULONG;
+    case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE: return types::DEVICE_MEM_CACHE_TYPE;
+    case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE: return types::UINT;
+    case CL_DEVICE_GLOBAL_MEM_SIZE: return types::ULONG;
+    //case CL_DEVICE_HALF_FP_CONFIG: return types::DEVICE_HALF_FP_CONFIG;
+    case CL_DEVICE_IMAGE_SUPPORT: return types::BOOL;
+    case CL_DEVICE_IMAGE2D_MAX_HEIGHT: return types::SIZE_T;
+    case CL_DEVICE_IMAGE2D_MAX_WIDTH: return types::SIZE_T;
+    case CL_DEVICE_IMAGE3D_MAX_DEPTH: return types::SIZE_T;
+    case CL_DEVICE_IMAGE3D_MAX_HEIGHT: return types::SIZE_T;
+    case CL_DEVICE_IMAGE3D_MAX_WIDTH: return types::SIZE_T;
+    case CL_DEVICE_LOCAL_MEM_SIZE: return types::ULONG;
+    case CL_DEVICE_LOCAL_MEM_TYPE: return types::DEVICE_LOCAL_MEM_TYPE;
+    case CL_DEVICE_MAX_CLOCK_FREQUENCY: return types::UINT;
+    case CL_DEVICE_MAX_COMPUTE_UNITS: return types::UINT;
+    case CL_DEVICE_MAX_CONSTANT_ARGS: return types::UINT;
+    case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: return types::ULONG;
+    case CL_DEVICE_MAX_MEM_ALLOC_SIZE: return types::ULONG;
+    case CL_DEVICE_MAX_PARAMETER_SIZE: return types::SIZE_T;
+    case CL_DEVICE_MAX_READ_IMAGE_ARGS: return types::UINT;
+    case CL_DEVICE_MAX_SAMPLERS: return types::UINT;
+    case CL_DEVICE_MAX_WORK_GROUP_SIZE: return types::SIZE_T;
+    case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: return types::UINT;
+    case CL_DEVICE_MAX_WORK_ITEM_SIZES: return types::SIZE_T_V;
+    case CL_DEVICE_MAX_WRITE_IMAGE_ARGS: return types::UINT;
+    case CL_DEVICE_MEM_BASE_ADDR_ALIGN: return types::UINT;
+    case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE: return types::UINT;
+    case CL_DEVICE_NAME: return types::STRING;
+    case CL_DEVICE_PLATFORM: return types::PLATFORM;
+    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR: return types::UINT;
+    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT: return types::UINT;
+    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT: return types::UINT;
+    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG: return types::UINT;
+    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT: return types::UINT;
+    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE: return types::UINT;
+    case CL_DEVICE_PROFILE: return types::STRING;
+    case CL_DEVICE_PROFILING_TIMER_RESOLUTION: return types::SIZE_T;
+    case CL_DEVICE_QUEUE_PROPERTIES: return types::COMMAND_QUEUE_PROPERTIES;
+    case CL_DEVICE_SINGLE_FP_CONFIG: return types::DEVICE_FP_CONFIG;
+    case CL_DEVICE_TYPE: return types::DEVICE_TYPE;
+    case CL_DEVICE_VENDOR: return types::STRING;
+    case CL_DEVICE_VENDOR_ID: return types::UINT;
+    case CL_DEVICE_VERSION: return types::STRING;
+    case CL_DRIVER_VERSION: return types::STRING;
+    default: ;
+  }
+  return types::UNKNOWN;
+}
+
+
+/* nsIVariant getDeviceInfo (in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLDevice::GetDeviceInfo(PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  WEBCL_GETINFO_MEDIATOR_SWITCH (aName, type, mWrapper, getDeviceInfo, mInternal,
+                                 variant, err, rv);
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
diff -r 450143d2d810 browser/components/webcl/src/WebCLDevice.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLDevice.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,69 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCLDEVICE_H_
+#define _WEBCLDEVICE_H_
+
+#include "WebCLCommon.h"
+#include "IWebCLDevice.h" // Generated from IWebCLDevice.idl
+#include "instance_registry.h"
+
+#include <CL/opencl.h>
+
+
+#define WEBCL_DEVICE_CLASSNAME "WebCLDevice"
+#define WEBCL_DEVICE_CID { 0xf5352722, 0x9a35, 0x405b, { 0x95, 0xae, 0x54, 0xd5, 0xb4, 0x99, 0x55, 0x76 } }
+#define WEBCL_DEVICE_CONTRACTID "@webcl.nokiaresearch.com/WebCLDevice;1"
+
+/** Implements IWebCLDevice interface. */
+class WebCLDevice : public IWebCLDevice, public WebCLCommon
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISECURITYCHECKEDCOMPONENT
+  NS_DECL_IWEBCLDEVICE
+
+  static nsresult getInstance (cl_device_id aInternal, WebCLDevice** aResultOut,
+                               WebCL_LibCLWrapper* aLibWrapper = 0);
+
+  WebCLDevice ();
+  cl_device_id getInternal () { return mInternal; }
+
+protected:
+  int getTypeForInfoName (int aName);
+
+private:
+  static InstanceRegistry<cl_device_id, WebCLDevice*> instanceRegistry;
+
+  ~WebCLDevice ();
+
+  cl_device_id mInternal;
+};
+
+#endif //_WEBCLDEVICE_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCLEvent.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLEvent.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,208 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCLEvent.h"
+#include "WebCLCommon.h"
+#include "WebCL_internal.h"
+#include "WebCL_clwrapper.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsISecurityCheckedComponent.h"
+
+
+NS_IMPL_ISUPPORTS2 (WebCLEvent, IWebCLEvent, nsISecurityCheckedComponent)
+WEBCL_SECURITY_CHECKED_IMPL (WebCLEvent)
+
+
+/* static */
+InstanceRegistry<cl_event, WebCLEvent*> WebCLEvent::instanceRegistry;
+
+
+/* static */
+nsresult WebCLEvent::getInstance (cl_event aInternal, WebCLEvent** aResultOut,
+                                  WebCL_LibCLWrapper* aLibWrapper)
+{
+  nsresult rv = NS_OK;
+
+  WebCLEvent* existing = 0;
+  if (instanceRegistry.findById (aInternal, &existing))
+  {
+    NS_IF_ADDREF (*aResultOut = existing);
+  }
+  else
+  {
+    nsCOMPtr<WebCLEvent> obj = do_CreateInstance (WEBCL_EVENT_CONTRACTID, &rv);
+    if (NS_FAILED (rv))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to create instance. rv=%d.", rv);
+      return rv;
+    }
+
+    obj->setWrapper (aLibWrapper);
+    obj->mInternal = aInternal;
+
+    instanceRegistry.add (obj->mInternal, obj);
+
+    NS_IF_ADDREF (*aResultOut = obj);
+  }
+
+  return rv;
+}
+
+
+WebCLEvent::WebCLEvent()
+  : IWebCLEvent(), WebCLCommon(),
+    mInternal(0)
+{
+  D_METHOD_START;
+}
+
+
+WebCLEvent::~WebCLEvent()
+{
+  D_METHOD_START;
+  if (mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (mWrapper)
+      mWrapper->releaseEvent (mInternal);
+    mInternal = 0;
+  }
+}
+
+
+int WebCLEvent::getTypeForInfoName (int aName)
+{
+  D_METHOD_START;
+  switch (aName)
+  {
+    // getInfo
+    case CL_EVENT_COMMAND_QUEUE: return types::COMMAND_QUEUE;
+    case CL_EVENT_CONTEXT: return types::CONTEXT;
+    case CL_EVENT_COMMAND_TYPE: return types::COMMAND_TYPE;
+    case CL_EVENT_COMMAND_EXECUTION_STATUS: return types::INT;
+    case CL_EVENT_REFERENCE_COUNT: return types::UINT;
+
+    // getProfilingInfo
+    case CL_PROFILING_COMMAND_QUEUED: return types::ULONG;
+    case CL_PROFILING_COMMAND_SUBMIT: return types::ULONG;
+    case CL_PROFILING_COMMAND_START: return types::ULONG;
+    case CL_PROFILING_COMMAND_END: return types::ULONG;
+    default: ;
+  }
+  return types::UNKNOWN;
+}
+
+
+/* nsIVariant getEventInfo (in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLEvent::GetEventInfo(PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  WEBCL_GETINFO_MEDIATOR_SWITCH (aName, type, mWrapper, getEventInfo, mInternal,
+                                 variant, err, rv);
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
+
+
+/* nsIVariant getEventProfilingInfo (in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLEvent::GetEventProfilingInfo(PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  WEBCL_GETINFO_MEDIATOR_SWITCH (aName, type, mWrapper, getEventProfilingInfo, mInternal,
+                                 variant, err, rv);
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
+
+
+/* void setUserEventStatus (in long aExecutionStatus); */
+NS_IMETHODIMP WebCLEvent::SetUserEventStatus(PRInt32 aExecutionStatus, JSContext *cx)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+
+  cl_int err = mWrapper->setUserEventStatus (mInternal, aExecutionStatus);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  return NS_OK;
+}
+
+
+/* void releaseCLResources (); */
+NS_IMETHODIMP WebCLEvent::ReleaseCLResources ()
+{
+  D_METHOD_START;
+  if (mWrapper && mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (CL_FAILED (mWrapper->releaseEvent (mInternal)))
+      D_LOG (LOG_LEVEL_WARNING, "Failed to release CL resources.");
+    mInternal = 0;
+  }
+  mWrapper = 0;
+  return NS_OK;
+}
diff -r 450143d2d810 browser/components/webcl/src/WebCLEvent.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLEvent.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,69 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCLEVENT_H_
+#define _WEBCLEVENT_H_
+
+#include "WebCLCommon.h"
+#include "IWebCLEvent.h" // Generated from IWebCLEvent.idl
+#include "instance_registry.h"
+
+#include <CL/opencl.h>
+
+
+#define WEBCL_EVENT_CLASSNAME "WebCLEvent"
+#define WEBCL_EVENT_CID { 0xcf7372e6, 0xf2ec, 0x467d, { 0x99, 0xdc, 0x9e, 0xeb, 0x75, 0x6b, 0xc3, 0xe3 } }
+#define WEBCL_EVENT_CONTRACTID "@webcl.nokiaresearch.com/WebCLEvent;1"
+
+/** Implements IWebCLEvent interface. */
+class WebCLEvent : public IWebCLEvent, public WebCLCommon
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISECURITYCHECKEDCOMPONENT
+  NS_DECL_IWEBCLEVENT
+
+  static nsresult getInstance (cl_event aInternal, WebCLEvent** aResultOut,
+                               WebCL_LibCLWrapper* aLibWrapper = 0);
+
+  WebCLEvent ();
+  cl_event getInternal () { return mInternal; }
+
+protected:
+  int getTypeForInfoName (int aName);
+
+private:
+  static InstanceRegistry<cl_event, WebCLEvent*> instanceRegistry;
+
+  ~WebCLEvent ();
+
+  cl_event mInternal;
+};
+
+#endif //_WEBCLEVENT_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCLKernel.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLKernel.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,621 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCLKernel.h"
+#include "WebCLCommon.h"
+#include "WebCL_internal.h"
+#include "WebCL_clwrapper.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsISecurityCheckedComponent.h"
+#include "nsStringAPI.h"
+
+
+NS_IMPL_ISUPPORTS2 (WebCLKernel, IWebCLKernel, nsISecurityCheckedComponent)
+WEBCL_SECURITY_CHECKED_IMPL (WebCLKernel)
+
+
+/* static */
+InstanceRegistry<cl_kernel, WebCLKernel*> WebCLKernel::instanceRegistry;
+
+
+/* static */
+nsresult WebCLKernel::getInstance (cl_kernel aInternal, WebCLKernel** aResultOut,
+                                   WebCL_LibCLWrapper* aLibWrapper)
+{
+  nsresult rv = NS_OK;
+
+  WebCLKernel* existing = 0;
+  if (instanceRegistry.findById (aInternal, &existing))
+  {
+    NS_IF_ADDREF (*aResultOut = existing);
+  }
+  else
+  {
+    nsCOMPtr<WebCLKernel> obj = do_CreateInstance (WEBCL_KERNEL_CONTRACTID, &rv);
+    if (NS_FAILED (rv))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to create instance. rv=%d.", rv);
+      return rv;
+    }
+
+    obj->setWrapper (aLibWrapper);
+    obj->mInternal = aInternal;
+
+    instanceRegistry.add (obj->mInternal, obj);
+
+    NS_IF_ADDREF (*aResultOut = obj);
+  }
+
+  return rv;
+}
+
+
+WebCLKernel::WebCLKernel()
+  : IWebCLKernel(), WebCLCommon(),
+    mInternal(0)
+{
+  D_METHOD_START;
+}
+
+
+WebCLKernel::~WebCLKernel()
+{
+  D_METHOD_START;
+  if (mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (mWrapper)
+      mWrapper->releaseKernel (mInternal);
+    mInternal = 0;
+  }
+}
+
+
+int WebCLKernel::getTypeForInfoName (int aName)
+{
+  D_METHOD_START;
+  switch (aName)
+  {
+    // getInfo
+    case CL_KERNEL_FUNCTION_NAME: return types::STRING;
+    case CL_KERNEL_NUM_ARGS: return types::UINT;
+    case CL_KERNEL_REFERENCE_COUNT: return types::UINT;
+    case CL_KERNEL_CONTEXT: return types::CONTEXT;
+    case CL_KERNEL_PROGRAM: return types::PROGRAM;
+
+    // getWorkGroupInfo
+    case CL_KERNEL_WORK_GROUP_SIZE: return types::SIZE_T;
+    case CL_KERNEL_COMPILE_WORK_GROUP_SIZE: return types::SIZE_T_V;
+    case CL_KERNEL_LOCAL_MEM_SIZE: return types::ULONG;
+    case CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: return types::SIZE_T;
+    case CL_KERNEL_PRIVATE_MEM_SIZE: return types::ULONG;
+
+    default: ;
+  }
+  return types::UNKNOWN;
+}
+
+
+/* nsIVariant getKernelInfo (in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLKernel::GetKernelInfo(PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  WEBCL_GETINFO_MEDIATOR_SWITCH (aName, type, mWrapper, getKernelInfo, mInternal,
+                                 variant, err, rv);
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
+
+
+/* nsIVariant getKernelWorkGroupInfo (in nsISupports aDevice, in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLKernel::GetKernelWorkGroupInfo(nsISupports *aDevice, PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+
+  NS_ENSURE_ARG_POINTER (aDevice);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<WebCLDevice> device = do_QueryInterface (aDevice, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  WEBCL_GETINFO_MEDIATOR_EXTRA_SWITCH (device->getInternal(), aName, type,
+                                       mWrapper, getKernelWorkGroupInfo, mInternal,
+                                       variant, err, rv);
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
+
+
+#define VARIANT_TO_CL_TYPE(Tcltype,Tvarianttype,Fvariantgetter,name) \
+  inline static nsresult name (nsIVariant* aVariant, Tcltype* aResultOut) { \
+    D_METHOD_START; \
+    NS_ENSURE_ARG_POINTER (aVariant); \
+    NS_ENSURE_ARG_POINTER (aResultOut); \
+    nsresult rv; \
+    Tvarianttype val; \
+    rv = aVariant->Fvariantgetter (&val); \
+    NS_ENSURE_SUCCESS (rv, rv); \
+    *aResultOut = (Tcltype)val; \
+    return NS_OK; \
+  }
+VARIANT_TO_CL_TYPE(cl_char, PRUint8, GetAsInt8, variantToCLChar)   // Yes, getAsInt8 returns PRUint8...
+VARIANT_TO_CL_TYPE(cl_uchar, PRUint8, GetAsUint8, variantToCLUChar)
+VARIANT_TO_CL_TYPE(cl_short, PRInt16, GetAsInt16, variantToCLShort)
+VARIANT_TO_CL_TYPE(cl_ushort, PRUint16, GetAsUint16, variantToCLUShort)
+VARIANT_TO_CL_TYPE(cl_int, PRInt32, GetAsInt32, variantToCLInt)
+VARIANT_TO_CL_TYPE(cl_uint, PRUint32, GetAsUint32, variantToCLUInt)
+VARIANT_TO_CL_TYPE(cl_long, PRInt64, GetAsInt64, variantToCLLong)
+VARIANT_TO_CL_TYPE(cl_ulong, PRUint32, GetAsUint32, variantToCLULong)
+VARIANT_TO_CL_TYPE(size_t, PRUint32, GetAsUint32, variantToCLSizeT) // NOTE: size_t to uint32
+VARIANT_TO_CL_TYPE(cl_bool, bool, GetAsBool, variantToCLBool)
+VARIANT_TO_CL_TYPE(cl_half, PRUint16, GetAsUint16, variantToCLHalf) // NOTE: cl_half to uint16
+VARIANT_TO_CL_TYPE(cl_float, float, GetAsFloat, variantToCLFloat)
+VARIANT_TO_CL_TYPE(cl_double, double, GetAsDouble, variantToCLDouble)
+
+
+/* void setKernelArg (in long aIndex, in nsIVariant aValue, [optional] in long aType); */
+NS_IMETHODIMP WebCLKernel::SetKernelArg(PRInt32 aIndex, nsIVariant *aValue, PRInt32 aType, JSContext *cx)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aValue);
+  NS_ENSURE_ARG_POINTER (cx);
+  nsresult rv = NS_OK;
+
+  if (aType == types::UNKNOWN)
+  {
+    PRUint16 variantType = 0;
+    rv = aValue->GetDataType (&variantType);
+    // If the type is unknown or user chose not to use explicit type, we'll try
+    // to guess it based on the type of the variant.
+    switch (variantType)
+    {
+      case nsIDataType::VTYPE_INT8: return SetKernelArg (aIndex, aValue, types::CHAR, cx);
+      case nsIDataType::VTYPE_INT16: return SetKernelArg (aIndex, aValue, types::SHORT, cx);
+      case nsIDataType::VTYPE_INT32: return SetKernelArg (aIndex, aValue, types::INT, cx);
+      case nsIDataType::VTYPE_INT64: return SetKernelArg (aIndex, aValue, types::LONG, cx);
+      case nsIDataType::VTYPE_UINT8: return SetKernelArg (aIndex, aValue, types::UCHAR, cx);
+      case nsIDataType::VTYPE_UINT16: return SetKernelArg (aIndex, aValue, types::USHORT, cx);
+      case nsIDataType::VTYPE_UINT32: return SetKernelArg (aIndex, aValue, types::UINT, cx);
+      case nsIDataType::VTYPE_UINT64: return SetKernelArg (aIndex, aValue, types::ULONG, cx);
+      case nsIDataType::VTYPE_FLOAT: return SetKernelArg (aIndex, aValue, types::FLOAT, cx);
+      case nsIDataType::VTYPE_DOUBLE: return SetKernelArg (aIndex, aValue, types::DOUBLE, cx);
+      case nsIDataType::VTYPE_BOOL: return SetKernelArg (aIndex, aValue, types::BOOL, cx);
+
+      case nsIDataType::VTYPE_CHAR:
+      case nsIDataType::VTYPE_WCHAR: return SetKernelArg (aIndex, aValue, types::CHAR, cx);
+
+      case nsIDataType::VTYPE_CHAR_STR:
+      case nsIDataType::VTYPE_WCHAR_STR:
+      case nsIDataType::VTYPE_UTF8STRING:
+      case nsIDataType::VTYPE_ASTRING:
+      case nsIDataType::VTYPE_CSTRING: return SetKernelArg (aIndex, aValue, types::STRING, cx);
+
+      case nsIDataType::VTYPE_INTERFACE:
+      case nsIDataType::VTYPE_INTERFACE_IS:
+      {
+        // Try conversions to supported WebCL interfaces.
+        nsCOMPtr<IWebCLMemoryObject> memObj;
+        rv = aValue->GetAsISupports (getter_AddRefs(memObj));
+        if (NS_SUCCEEDED (rv)) return SetKernelArg (aIndex, aValue, types::MEMORY_OBJECT, cx);
+
+        nsCOMPtr<IWebCLSampler> samplerObj;
+        rv = aValue->GetAsISupports (getter_AddRefs(samplerObj));
+        if (NS_SUCCEEDED (rv)) return SetKernelArg (aIndex, aValue, types::SAMPLER, cx);
+
+        // None found, intentional leak to default
+      }
+
+      case nsIDataType::VTYPE_ARRAY:
+      case nsIDataType::VTYPE_EMPTY_ARRAY:
+        D_LOG (LOG_LEVEL_ERROR, "Array support not implemented.");
+        WebCL_reportJSError (cx, "WebCLKernel::setKernelArg: Array support not implemented.");
+        return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+
+      case nsIDataType::VTYPE_EMPTY:
+      case nsIDataType::VTYPE_VOID:
+      case nsIDataType::VTYPE_ID:
+      default:
+        D_LOG (LOG_LEVEL_ERROR,
+               "Unable to guess type from variant (type %u) and no type given by the user.",
+               variantType);
+        WebCL_reportJSError (cx, "WebCLKernel::setKernelArg: Unable to guess type from variant (type %u) and no type given by the user.",
+                             variantType);
+        return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+    }
+  }
+
+  size_t sze = 0;
+  void* value = 0;
+
+  switch (aType)
+  {
+    case types::BYTE:
+    case types::CHAR:
+      value = (void*)malloc (sze = sizeof (cl_char));
+      if (value)
+        rv = variantToCLChar (aValue, (cl_char*)value);
+      break;
+
+    case types::UCHAR:
+      value = (void*)malloc (sze = sizeof (cl_uchar));
+      if (value)
+        rv = variantToCLUChar (aValue, (cl_uchar*)value);
+      break;
+
+    case types::SHORT:
+      value = (void*)malloc (sze = sizeof (cl_short));
+      if (value)
+        rv = variantToCLShort (aValue, (cl_short*)value);
+      break;
+
+    case types::USHORT:
+      value = (void*)malloc (sze = sizeof (cl_ushort));
+      if (value)
+        rv = variantToCLUShort (aValue, (cl_ushort*)value);
+      break;
+
+    case types::BUILD_STATUS:
+    case types::INT:
+      value = (void*)malloc (sze = sizeof (cl_int));
+      if (value)
+        rv = variantToCLInt (aValue, (cl_int*)value);
+      break;
+
+    case types::ADRESSING_MODE:
+    case types::CHANNEL_ORDER:
+    case types::CHANNEL_TYPE:
+    case types::COMMAND_TYPE:
+    case types::DEVICE_LOCAL_MEM_TYPE:
+    case types::DEVICE_MEM_CACHE_TYPE:
+    case types::FILTER_MODE:
+    case types::GL_OBJECT_TYPE:
+    case types::MEM_OBJECT_TYPE:
+    case types::UINT:
+      value = (void*)malloc (sze = sizeof (cl_uint));
+      if (value)
+        rv = variantToCLUInt (aValue, (cl_uint*)value);
+      break;
+
+    case types::LONG:
+      value = (void*)malloc (sze = sizeof (cl_long));
+      if (value)
+        rv = variantToCLLong (aValue, (cl_long*)value);
+      break;
+
+    case types::COMMAND_QUEUE_PROPERTIES: // bitfield
+    case types::DEVICE_EXEC_CAPABILITIES: // bitfield
+    case types::DEVICE_FP_CONFIG: // bitfield
+    case types::DEVICE_TYPE: // bitfield
+    case types::MAP_FLAGS: // bitfield
+    case types::MEM_FLAGS: // bitfield
+    case types::ULONG:
+      value = (void*)malloc (sze = sizeof (cl_ulong));
+      if (value)
+        rv = variantToCLULong (aValue, (cl_ulong*)value);
+      break;
+
+    case types::BOOL:
+      value = (void*)malloc (sze = sizeof (cl_bool));
+      if (value)
+        rv = variantToCLBool (aValue, (cl_bool*)value);
+      break;
+
+    case types::SIZE_T:
+      value = (void*)malloc (sze = sizeof (size_t));
+      if (value)
+        rv = variantToCLSizeT (aValue, (size_t*)value);
+      break;
+
+    case types::HALF:
+      value = (void*)malloc (sze = sizeof (cl_half));
+      if (value)
+        rv = variantToCLHalf (aValue, (cl_half*)value);
+      break;
+
+    case types::FLOAT:
+      value = (void*)malloc (sze = sizeof (cl_float));
+      if (value)
+        rv = variantToCLFloat (aValue, (cl_float*)value);
+      break;
+
+    case types::DOUBLE:
+      value = (void*)malloc (sze = sizeof (cl_double));
+      if (value)
+        rv = variantToCLDouble (aValue, (cl_double*)value);
+      break;
+
+    case types::STRING:
+    {
+      nsCString str;
+      rv = aValue->GetAsACString (str);
+      if (NS_SUCCEEDED (rv))
+      {
+        cl_int err = mWrapper->setKernelArg (mInternal, aIndex, str.Length () + 1,
+                                             (void*)str.get ());
+        ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+        ENSURE_CL_OP_SUCCESS (err);
+      }
+      break;
+    }
+
+    case types::BYTE_V:
+    case types::CHAR_V:
+    case types::UCHAR_V:
+    case types::SHORT_V:
+    case types::USHORT_V:
+    case types::CONTEXT_PROPERTIES:
+    case types::INT_V:
+    case types::UINT_V:
+    case types::LONG_V:
+    case types::ULONG_V:
+    case types::BOOL_V:
+    case types::SIZE_T_V:
+    case types::HALF_V:
+    case types::FLOAT_V:
+    case types::DOUBLE_V:
+    case types::STRING_V:
+      D_LOG (LOG_LEVEL_ERROR, "Array types are not supported.");
+      WebCL_reportJSError (cx, "WebCLKernel::setKernelArg: Array types are not supported.");
+      return WEBCL_XPCOM_ERROR; //NS_ERROR_NOT_IMPLEMENTED;
+
+    case types::MEMORY_OBJECT:
+    {
+      nsCOMPtr<nsISupports> isu;
+      rv = aValue->GetAsISupports (getter_AddRefs(isu));
+      if (NS_FAILED (rv)) break;
+      nsCOMPtr<WebCLMemoryObject> memObject = do_QueryInterface (isu, &rv);
+      if (NS_FAILED (rv)) break;
+      cl_mem wrapped = memObject->getInternal ();
+      cl_int wrErr = mWrapper->setKernelArg (mInternal, aIndex, sizeof(cl_mem),
+                                             (void*)&wrapped);
+      ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+      ENSURE_CL_OP_SUCCESS (wrErr);
+      return NS_OK;
+    }
+
+    case types::SAMPLER:
+    {
+      nsCOMPtr<nsISupports> isu;
+      rv = aValue->GetAsISupports (getter_AddRefs(isu));
+      if (NS_FAILED (rv)) break;
+      nsCOMPtr<WebCLSampler> sampler = do_QueryInterface (isu, &rv);
+      if (NS_FAILED (rv)) break;
+      cl_sampler wrapped = sampler->getInternal ();
+      cl_int wrErr = mWrapper->setKernelArg (mInternal, aIndex, sizeof(cl_sampler),
+                                             (void*)&wrapped);
+      ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+      ENSURE_CL_OP_SUCCESS (wrErr);
+      return NS_OK;
+    }
+
+    case types::PLATFORM:
+    {
+      nsCOMPtr<nsISupports> isu;
+      rv = aValue->GetAsISupports (getter_AddRefs(isu));
+      if (NS_FAILED (rv)) break;
+      nsCOMPtr<WebCLPlatform> platform = do_QueryInterface (isu, &rv);
+      if (NS_FAILED (rv)) break;
+      cl_platform_id wrapped = platform->getInternal ();
+      cl_int wrErr = mWrapper->setKernelArg (mInternal, aIndex, sizeof(cl_platform_id),
+                                             (void*)&wrapped);
+      ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+      ENSURE_CL_OP_SUCCESS (wrErr);
+      return NS_OK;
+    }
+
+    case types::DEVICE:
+    {
+      nsCOMPtr<nsISupports> isu;
+      rv = aValue->GetAsISupports (getter_AddRefs(isu));
+      if (NS_FAILED (rv)) break;
+      nsCOMPtr<WebCLDevice> device = do_QueryInterface (isu, &rv);
+      if (NS_FAILED (rv)) break;
+      cl_device_id wrapped = device->getInternal ();
+      cl_int wrErr = mWrapper->setKernelArg (mInternal, aIndex, sizeof(cl_device_id),
+                                             (void*)&wrapped);
+      ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+      ENSURE_CL_OP_SUCCESS (wrErr);
+      return NS_OK;
+    }
+
+    case types::CONTEXT:
+    {
+      nsCOMPtr<nsISupports> isu;
+      rv = aValue->GetAsISupports (getter_AddRefs(isu));
+      if (NS_FAILED (rv)) break;
+      nsCOMPtr<WebCLContext> context = do_QueryInterface (isu, &rv);
+      if (NS_FAILED (rv)) break;
+      cl_context wrapped = context->getInternal ();
+      cl_int wrErr = mWrapper->setKernelArg (mInternal, aIndex, sizeof(cl_context),
+                                             (void*)&wrapped);
+      ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+      ENSURE_CL_OP_SUCCESS (wrErr);
+      return NS_OK;
+    }
+
+    case types::COMMAND_QUEUE:
+    {
+      nsCOMPtr<nsISupports> isu;
+      rv = aValue->GetAsISupports (getter_AddRefs(isu));
+      if (NS_FAILED (rv)) break;
+      nsCOMPtr<WebCLCommandQueue> cmdQueue = do_QueryInterface (isu, &rv);
+      if (NS_FAILED (rv)) break;
+      cl_command_queue wrapped = cmdQueue->getInternal ();
+      cl_int wrErr = mWrapper->setKernelArg (mInternal, aIndex, sizeof(cl_command_queue),
+                                             (void*)&wrapped);
+      ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+      ENSURE_CL_OP_SUCCESS (wrErr);
+      return NS_OK;
+    }
+
+    case types::PROGRAM:
+    {
+      nsCOMPtr<nsISupports> isu;
+      rv = aValue->GetAsISupports (getter_AddRefs(isu));
+      if (NS_FAILED (rv)) break;
+      nsCOMPtr<WebCLProgram> program = do_QueryInterface (isu, &rv);
+      if (NS_FAILED (rv)) break;
+      cl_program wrapped = program->getInternal ();
+      cl_int wrErr = mWrapper->setKernelArg (mInternal, aIndex, sizeof(cl_program),
+                                             (void*)&wrapped);
+      ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+      ENSURE_CL_OP_SUCCESS (wrErr);
+      return NS_OK;
+    }
+
+    case types::KERNEL:
+    {
+      nsCOMPtr<nsISupports> isu;
+      rv = aValue->GetAsISupports (getter_AddRefs(isu));
+      if (NS_FAILED (rv)) break;
+      nsCOMPtr<WebCLKernel> kernel = do_QueryInterface (isu, &rv);
+      if (NS_FAILED (rv)) break;
+      cl_kernel wrapped = kernel->getInternal ();
+      cl_int wrErr = mWrapper->setKernelArg (mInternal, aIndex, sizeof(cl_kernel),
+                                             (void*)&wrapped);
+      ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+      ENSURE_CL_OP_SUCCESS (wrErr);
+      return NS_OK;
+    }
+
+    case types::EVENT:
+    {
+      nsCOMPtr<nsISupports> isu;
+      rv = aValue->GetAsISupports (getter_AddRefs(isu));
+      if (NS_FAILED (rv)) break;
+      nsCOMPtr<WebCLEvent> event = do_QueryInterface (isu, &rv);
+      if (NS_FAILED (rv)) break;
+      cl_event wrapped = event->getInternal ();
+      cl_int wrErr = mWrapper->setKernelArg (mInternal, aIndex, sizeof(cl_event),
+                                             (void*)&wrapped);
+      ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+      ENSURE_CL_OP_SUCCESS (wrErr);
+      return NS_OK;
+    }
+
+    default:
+      D_LOG (LOG_LEVEL_ERROR, "Unsupported type %d at argument index %u", aType, aIndex);
+      WebCL_reportJSError (cx, "WebCLKernel::setKernelArg: Unsupported type %d at argument index %u.", aType, aIndex);
+      //rv = NS_ERROR_INVALID_ARG;
+      return WEBCL_XPCOM_ERROR;
+  }
+
+  if (NS_SUCCEEDED (rv))
+  {
+    if (value)
+    {
+      cl_int err = mWrapper->setKernelArg (mInternal, aIndex, sze, value);
+      ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+      ENSURE_CL_OP_SUCCESS (err);
+
+    }
+    else
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Memory allocation failed for kernel argument at index %d.", aIndex);
+      WebCL_reportJSError (cx, "WebCLKernel::setKernelArg: Memory allocation failed for kernel argument at index %d.", aIndex);
+      rv = WEBCL_XPCOM_ERROR; //NS_ERROR_OUT_OF_MEMORY;
+    }
+  }
+  else
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to convert kernel argument at index %d.", aIndex);
+    WebCL_reportJSError (cx, "WebCLKernel::setKernelArg: Failed to convert kernel argument at index %d.", aIndex);
+    rv = WEBCL_XPCOM_ERROR;
+  }
+
+  if (value)
+    free (value);
+
+  return rv;
+}
+
+
+/* void setKernelArgLocal (in long aIndex, in unsigned long aSize); */
+NS_IMETHODIMP WebCLKernel::SetKernelArgLocal(PRInt32 aIndex, PRUint32 aSize, JSContext *cx)
+{
+  D_METHOD_START;
+  nsresult rv = NS_OK;
+  NS_ENSURE_ARG_POINTER (cx);
+
+  cl_int err = mWrapper->setKernelArg (mInternal, aIndex, aSize, 0);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  return rv;
+}
+
+
+/* void releaseCLResources (); */
+NS_IMETHODIMP WebCLKernel::ReleaseCLResources ()
+{
+  D_METHOD_START;
+  if (mWrapper && mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (CL_FAILED (mWrapper->releaseKernel (mInternal)))
+      D_LOG (LOG_LEVEL_WARNING, "Failed to release CL resources.");
+    mInternal = 0;
+  }
+  mWrapper = 0;
+  return NS_OK;
+}
diff -r 450143d2d810 browser/components/webcl/src/WebCLKernel.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLKernel.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,69 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCLKERNEL_H_
+#define _WEBCLKERNEL_H_
+
+#include "WebCLCommon.h"
+#include "IWebCLKernel.h" // Generated from IWebCLKernel.idl
+#include "instance_registry.h"
+
+#include <CL/opencl.h>
+
+
+#define WEBCL_KERNEL_CLASSNAME "WebCLKernel"
+#define WEBCL_KERNEL_CID { 0x5d1be1d7, 0xaad2, 0x4eb3, { 0x91, 0x8b, 0xe9, 0x55, 0x10, 0x79, 0xd6, 0x34 } }
+#define WEBCL_KERNEL_CONTRACTID "@webcl.nokiaresearch.com/WebCLKernel;1"
+
+/** Implements IWebCLKernel interface. */
+class WebCLKernel : public IWebCLKernel, public WebCLCommon
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISECURITYCHECKEDCOMPONENT
+  NS_DECL_IWEBCLKERNEL
+
+  static nsresult getInstance (cl_kernel aInternal, WebCLKernel** aResultOut,
+                               WebCL_LibCLWrapper* aLibWrapper = 0);
+
+  WebCLKernel ();
+  cl_kernel getInternal () { return mInternal; }
+
+protected:
+  int getTypeForInfoName (int aName);
+
+private:
+  static InstanceRegistry<cl_kernel, WebCLKernel*> instanceRegistry;
+
+  ~WebCLKernel ();
+
+  cl_kernel mInternal;
+};
+
+#endif //_WEBCLKERNEL_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCLLogger.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLLogger.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,208 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+
+#include "WebCLLogger.h"
+
+// Ensure vsnprintf is enabled on gcc:
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+
+#undef _XOPEN_SOURCE
+#define _XOPEN_SOURCE = 500
+
+#ifndef _ISOC99_SOURCE
+#define _ISOC99_SOURCE
+#endif
+
+// Prevent MSVC warnings about freopen
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <cstdlib>
+#include <cstdio>
+#include <stdarg.h>
+
+
+FILE* webcl_log_file = stderr;
+int webcl_log_level = WEBCL_LOG_LEVEL_DEFAULT;
+
+#ifdef WEBCL_LOG_TO_FILE
+#include <ctime>
+# ifndef WIN32
+# include <cstring>
+# include <cerrno>
+# endif
+#endif
+
+
+#ifdef WIN32
+
+#include "windows.h"
+
+void webcl_init_logging ()
+{
+  static bool initialized = false;
+  if (!initialized)
+  {
+    initialized = true; // Must set initialized here to prevent recursion.
+    #ifdef WEBCL_LOG_TO_FILE
+    if ((webcl_log_file = fopen (WEBCL_LOG_TO_FILE, "a")) == NULL)
+    {
+      AllocConsole();
+      freopen("conout$", "w", stderr);
+      webcl_log_file = stderr;
+      D_PRINT ("Failed to open log file \"%s\".", WEBCL_LOG_TO_FILE);
+    }
+    else
+    {
+      time_t t = time(NULL);
+      struct tm *tmp = localtime(&t);
+      char timeStr[30] = {0};
+      strftime (timeStr, 30, "%Y-%m-%d %M:%H:%S %Z", tmp);
+      D_PRINT_RAW (" =============================================================================\n"
+      "  WebCL log file opened %s.\n"
+      " =============================================================================\n",
+      timeStr);
+    }
+    #else //WEBCL_LOG_TO_FILE
+    AllocConsole();
+    freopen("conin$", "r", stdin);
+    freopen("conout$", "w", stdout);
+    freopen("conout$", "w", stderr);
+    #endif //WEBCL_LOG_TO_FILE
+  }
+}
+
+#else //WIN32
+
+void webcl_init_logging ()
+{
+  static bool initialized = false;
+  if (!initialized)
+  {
+    char* s = getenv("D_LOG_LEVEL");
+    if (s)
+    {
+      webcl_log_level = atoi(s);
+    }
+    initialized = true; // Must set initialized here to prevent recursion.
+    #ifdef WEBCL_LOG_TO_FILE
+    if ((webcl_log_file = fopen (WEBCL_LOG_TO_FILE, "a")) == NULL)
+    {
+      webcl_log_file = stderr;
+      D_PRINT ("Failed to open log file \"%s\": %s", WEBCL_LOG_TO_FILE, strerror(errno));
+    }
+    else
+    {
+      time_t t = time(NULL);
+      struct tm *tmp = localtime(&t);
+      char timeStr[30] = {0};
+      strftime (timeStr, 30, "%Y-%m-%d %M:%H:%S %Z", tmp);
+      D_PRINT_RAW (" =============================================================================\n"
+      "  WebCL log file opened %s.\n"
+      " =============================================================================\n",
+      timeStr);
+    }
+    #endif //WEBCL_LOG_TO_FILE
+  }
+}
+
+#endif //WIN32
+
+
+#include "nsServiceManagerUtils.h"
+#include "nsIConsoleService.h"
+#include "nsStringAPI.h"
+#include <cstdarg>
+
+void webcl_log_to_browser_console (char const* message)
+{
+  if (!message)
+    return;
+
+  char const* title = "WebCL: ";
+  size_t titleLen = strlen (title);
+  size_t messageLen = strlen (message);
+  char* titledMessage = (char*)malloc (titleLen + messageLen + 1);
+  if (!titledMessage)
+    return;
+
+  strncpy (titledMessage, title, titleLen);
+  strncat (titledMessage, message, messageLen);
+
+  nsCOMPtr<nsIConsoleService> consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+  if (!consoleService)
+  {
+    // Failed to get console service!
+    return;
+  }
+
+  nsCString msg(titledMessage);
+  consoleService->LogStringMessage(NS_ConvertUTF8toUTF16(message).get());
+}
+
+
+void webcl_log_to_browser_console_v (char const* format, ...)
+{
+  int initialSize = 128;  //Initial buffer size
+  char* buf = (char*) malloc (initialSize);
+  va_list ap;
+  va_start (ap, format);
+  int n = vsnprintf (buf, initialSize, format, ap);
+  va_end (ap);
+  if (n >= initialSize)
+  {
+    char* tmp = buf;
+    buf = (char*) realloc (buf, n+1);
+    if (!buf)
+    {
+      free (tmp);
+      return;
+    }
+    va_start (ap, format);
+    n = vsnprintf (buf, n, format, ap);
+    va_end (ap);
+  }
+  if (n < 0)
+  {
+    // vsnprintf failed
+    free (buf);
+    return;
+  }
+
+  webcl_log_to_browser_console (buf);
+  free (buf);
+}
+
+
+bool webcl_log_check_level (int level)
+{
+  return level <= webcl_log_level;
+}
diff -r 450143d2d810 browser/components/webcl/src/WebCLLogger.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLLogger.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,155 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+
+#ifndef _WEBCLLOGGER_H_
+#define _WEBCLLOGGER_H_
+
+#include <cstdlib>
+#include <cstdio>
+
+// Logging-related functionality:
+
+/* Log levels:
+ *   0: none
+ *   1: errors
+ *   2: warnings
+ *   3: info
+ *   4: debug
+ *   >4: all (reserved)
+ */
+#define LOG_LEVEL_NONE      0
+#define LOG_LEVEL_ERROR     1
+#define LOG_LEVEL_WARNING   2
+#define LOG_LEVEL_INFO      3
+#define LOG_LEVEL_DEBUG     4
+
+#ifndef WEBCL_LOG_LEVEL_DEFAULT
+# define WEBCL_LOG_LEVEL_DEFAULT 1
+#endif
+
+extern FILE* webcl_log_file;  // default: stderr or WEBCL_LOG_TO_FILE
+extern int webcl_log_level;   // default: WEBCL_LOG_LEVEL_DEFAULT
+
+// INTERNAL
+void webcl_log_to_browser_console (char const* message);
+void webcl_log_to_browser_console_v (char const* format, ...);
+
+/** This INTERNAL FUNCTION handles logging system initialization. */
+void webcl_init_logging ();
+/** This INTERNAL FUNCTION performs logging level checks. */
+bool webcl_log_check_level (int level);
+
+#ifdef WEBCL_ENABLE_LOG
+
+/**
+ * \fn D_PRINT_RAW(...)
+ * A variadic macro for printing arbitrary text to log output. In operation
+ * only if logging is enabled.
+ */
+#  define D_PRINT_RAW(...) do{ \
+  webcl_init_logging(); \
+  fprintf(webcl_log_file, __VA_ARGS__);fflush(webcl_log_file);\
+  /*webcl_log_to_browser_console_v (__VA_ARGS__);*/ \
+}while(0)
+
+/** \fn D_PRINT(fmt, ...)
+ * A variadic macro for printing arbitrary text with source line information
+ * to log output. In operation only if logging is enabled.
+ * \param fmt Format argument similar to printf.
+ * \see printf
+ */
+# ifdef WIN32
+#  define D_PRINT(...) do{D_PRINT_RAW(" # # # [%s:%-4d] ", __FILE__, __LINE__, __VA_ARGS__); \
+D_PRINT_RAW(__VA_ARGS__); D_PRINT_RAW("\n");}while(0)
+# else
+#  define D_PRINT(fmt, ...) D_PRINT_RAW(" # # # [%s:%-4d] " fmt "\n", \
+__FILE__, __LINE__, ##__VA_ARGS__)
+# endif /* WIN32 */
+
+
+/** \fn D_LOG(lev, fmt, ...)
+ * A variadic macro for printing log messages to log output webcl_log_file.
+ * The message is sent to output if the value of \c lev is lower than
+ * the current logging level.
+ * In operation only if logging is enabled.
+ * \param lev Logging level assigned to the following message.
+ * \param fmt Format argument similar to printf.
+ * \see webcl_log_file
+ * \see webcl_log_level
+ * \see printf
+ */
+#  ifdef WIN32
+#   define D_LOG(lev, ...) do{if(webcl_log_check_level(lev)){ \
+D_PRINT_RAW(" ##LOG## [%s:%-4d %s] ", __FILE__, __LINE__,__FUNCTION__); \
+D_PRINT_RAW(__VA_ARGS__); D_PRINT_RAW("\n");}}while(0)
+#  else
+#   define D_LOG(lev, fmt, ...) do{if(webcl_log_check_level(lev)){ \
+D_PRINT_RAW(" ##LOG## [%s:%-4d %s] "\
+fmt "\n", __FILE__, __LINE__,\
+__FUNCTION__, ##__VA_ARGS__);}}while(0)
+#  endif /* WIN32 */
+
+#else //WEBCL_ENABLE_LOG
+# define D_PRINT_RAW(...) do{}while(0)
+# define D_PRINT(...) do{}while(0)
+# define D_LOG(...) do{}while(0)
+#endif //WEBCL_ENABLE_LOG
+
+
+/** \fn D_METHOD_START
+ * This macro marks the beginning of generally important function calls.
+ * Used for runtime function call tracing to log.
+ */
+#ifdef WEBCL_TRACE_FUNCTIONS
+# define D_METHOD_START D_PRINT_RAW(" ##LOG## [%s:%-4d] ============ Entering function %s ============\n", \
+__FILE__, __LINE__,__FUNCTION__)
+#else //DWEBCL_TRACE_FUNCTIONS
+# define D_METHOD_START do{}while(0)
+#endif //DWEBCL_TRACE_FUNCTIONS
+
+#if 0
+/** \fn D_TRACE_ALLOC
+ * This macro is used for logging dynamic memory allocation.
+ * \fn D_TRACK_RELEASE
+ * This macro is used for logging releasing of dynamically allocated memory.
+ */
+#ifdef WEBCL_TRACE_ALLOCS
+# define D_TRACE_ALLOC(bytes,type,p) D_PRINT_RAW(" ##LOG## [%s:%-4d %s]  ALLOC  %ld bytes in (" #type "*)%p\n", \
+__FILE__, __LINE__,__FUNCTION__, bytes, type, p)
+# define D_TRACE_RELEASE(type,p) D_PRINT_RAW(" ##LOG## [%s:%-4d %s]  RELEASE  (" #type "*)%p\n", \
+__FILE__, __LINE__,__FUNCTION__, type, p)
+#else //WEBCL_TRACK_ALLOCS
+# define D_TRACK_ALLOC do{}while(0)
+# define D_TRACK_RELEASE do{}while(0)
+#endif //WEBCL_TRACK_ALLOCS
+#endif
+
+
+#endif //_WEBCLLOGGER_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCLMemoryObject.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLMemoryObject.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,295 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCLMemoryObject.h"
+#include "WebCLCommon.h"
+#include "WebCL_internal.h"
+#include "WebCL_clwrapper.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsISecurityCheckedComponent.h"
+
+#include "jsapi.h"
+#include "jsproxy.h"
+#include "jswrapper.h"
+
+
+NS_IMPL_ISUPPORTS2 (WebCLMemoryObject, IWebCLMemoryObject, nsISecurityCheckedComponent)
+WEBCL_SECURITY_CHECKED_IMPL (WebCLMemoryObject)
+
+
+/* static */
+InstanceRegistry<cl_mem, WebCLMemoryObject*> WebCLMemoryObject::instanceRegistry;
+
+
+/* static */
+nsresult WebCLMemoryObject::getInstance (cl_mem aInternal, WebCLMemoryObject** aResultOut,
+                                         WebCL_LibCLWrapper* aLibWrapper)
+{
+  D_METHOD_START;
+  nsresult rv = NS_OK;
+
+  WebCLMemoryObject* existing = 0;
+  if (instanceRegistry.findById (aInternal, &existing))
+  {
+    D_LOG (LOG_LEVEL_DEBUG, "Found existing instance %p", existing);
+    NS_IF_ADDREF (*aResultOut = existing);
+  }
+  else
+  {
+    nsCOMPtr<WebCLMemoryObject> obj = do_CreateInstance (WEBCL_MEMORYOBJECT_CONTRACTID, &rv);
+    if (NS_FAILED (rv))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to create instance. rv=%d.", rv);
+      return rv;
+    }
+    D_LOG (LOG_LEVEL_DEBUG, "No existing instance, created %p", (WebCLMemoryObject*)obj);
+
+    obj->setWrapper (aLibWrapper);
+    obj->mInternal = aInternal;
+
+    instanceRegistry.add (obj->mInternal, obj);
+
+    NS_IF_ADDREF (*aResultOut = obj);
+  }
+
+  return rv;
+}
+
+
+WebCLMemoryObject::WebCLMemoryObject()
+  : IWebCLMemoryObject(), WebCLCommon(),
+    mInternal(0)
+{
+  D_METHOD_START;
+}
+
+
+WebCLMemoryObject::~WebCLMemoryObject()
+{
+  D_METHOD_START;
+  if (mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (mWrapper)
+      mWrapper->releaseMemObject (mInternal);
+    mInternal = 0;
+  }
+}
+
+
+int WebCLMemoryObject::getTypeForInfoName (int aName)
+{
+  D_METHOD_START;
+  switch (aName)
+  {
+    // getInfo:
+    case CL_MEM_TYPE: return types::MEM_OBJECT_TYPE;
+    case CL_MEM_FLAGS: return types::MEM_FLAGS;
+    case CL_MEM_SIZE: return types::SIZE_T;
+    //NOT SUPPORTED: case CL_MEM_HOST_PTR: return types::
+    case CL_MEM_MAP_COUNT: return types::UINT;
+    case CL_MEM_REFERENCE_COUNT: return types::UINT;
+    case CL_MEM_CONTEXT: return types::CONTEXT;
+    case CL_MEM_ASSOCIATED_MEMOBJECT: return types::MEMORY_OBJECT;
+    case CL_MEM_OFFSET: return types::SIZE_T;
+    //NOT SUPPORTED: case CL_MEM_D3D10_RESOURCE_KHR: return types::
+
+    // getImageInfo:
+    case CL_IMAGE_FORMAT: return types::IMAGE_FORMAT;
+    case CL_IMAGE_ELEMENT_SIZE: return types::SIZE_T;
+    case CL_IMAGE_ROW_PITCH: return types::SIZE_T;
+    case CL_IMAGE_SLICE_PITCH: return types::SIZE_T;
+    case CL_IMAGE_WIDTH: return types::SIZE_T;
+    case CL_IMAGE_HEIGHT: return types::SIZE_T;
+    case CL_IMAGE_DEPTH: return types::SIZE_T;
+    //NOT SUPPORTED: case CL_IMAGE_D3D10_SUBRESOURCE_KHR: return types::
+
+    default: ;
+  }
+  return types::UNKNOWN;
+}
+
+
+/* nsIVariant getMemObjectInfo (in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLMemoryObject::GetMemObjectInfo(PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  WEBCL_GETINFO_MEDIATOR_SWITCH (aName, type, mWrapper, getMemObjectInfo, mInternal,
+                                 variant, err, rv);
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
+
+
+/* nsIVariant getImageInfo (in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLMemoryObject::GetImageInfo(PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  WEBCL_GETINFO_MEDIATOR_SWITCH (aName, type, mWrapper, getImageInfo, mInternal,
+                                 variant, err, rv);
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
+
+
+/* IWebCLMemoryObject createSubBuffer (in T_WebCLMemFlags aFlags, in nsIVariant aBufferRegion); */
+NS_IMETHODIMP WebCLMemoryObject::CreateSubBuffer(T_WebCLMemFlags aFlags, nsIVariant *aBufferRegion, JSContext *cx, IWebCLMemoryObject **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aBufferRegion);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  // The variant must be an object
+  PRUint16 variantType = 0;
+  rv = aBufferRegion->GetDataType (&variantType);
+  if ( !(variantType == nsIDataType::VTYPE_INTERFACE
+         || variantType == nsIDataType::VTYPE_INTERFACE_IS))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Variant is not interface.");
+    WebCL_reportJSError (cx, "%s: Invalid buffer region: not an object.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  if (!cx)
+  {
+    nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv);
+    NS_ENSURE_SUCCESS (rv, rv);
+    cx = stack->GetSafeJSContext ();
+    NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE);
+  }
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+  js::Value jsVal;
+  rv = xpc->VariantToJS(cx, JS_GetGlobalObject(cx), aBufferRegion, &jsVal);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  if (!jsVal.isObject())
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Variant is not an object.");
+    WebCL_reportJSError (cx, "%s: Invalid buffer region: not an object.", __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_INVALID_ARG;
+  }
+
+  JSObject* jsObj = jsVal.toObjectOrNull ();
+  if (jsObj && js::IsObjectProxy (jsObj))
+  {
+    jsObj = js::UnwrapObject (jsObj);
+  }
+
+  if (!jsObj)
+  {
+    // jsval is reported as object but failed to either convert to such or unwrap.
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  js::Value propOrigin;
+  if (!JS_LookupProperty (cx, jsObj, "origin", &propOrigin))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to read origin property.");
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  js::Value propSize;
+  if (!JS_LookupProperty (cx, jsObj, "size", &propSize))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to read size property.");
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  cl_buffer_region region;
+  region.origin = propOrigin.toInt32 ();
+  region.size = propSize.toInt32 ();
+
+  cl_int err = CL_SUCCESS;
+  cl_mem mem = mWrapper->createSubBuffer (mInternal, aFlags, CL_BUFFER_CREATE_TYPE_REGION,
+                                          (void const*)&region, &err);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLMemoryObject> xpcObj;
+  rv = WebCLMemoryObject::getInstance (mem, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* void releaseCLResources (); */
+NS_IMETHODIMP WebCLMemoryObject::ReleaseCLResources ()
+{
+  D_METHOD_START;
+  if (mWrapper && mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (CL_FAILED (mWrapper->releaseMemObject (mInternal)))
+      D_LOG (LOG_LEVEL_WARNING, "Failed to release CL resources.");
+    mInternal = 0;
+  }
+  mWrapper = 0;
+  return NS_OK;
+}
diff -r 450143d2d810 browser/components/webcl/src/WebCLMemoryObject.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLMemoryObject.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,69 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCL_MEMORYOBJECT_H_
+#define _WEBCL_MEMORYOBJECT_H_
+
+#include "WebCLCommon.h"
+#include "IWebCLMemoryObject.h" // Generated from IWebCLMemoryObject.idl
+#include "instance_registry.h"
+
+#include <CL/opencl.h>
+
+
+#define WEBCL_MEMORYOBJECT_CLASSNAME "WebCLMemoryObject"
+#define WEBCL_MEMORYOBJECT_CID { 0xe677e482, 0x49e5, 0x40de, { 0xba, 0x4f, 0x0e, 0x71, 0xf3, 0x01, 0x28, 0x6b } }
+#define WEBCL_MEMORYOBJECT_CONTRACTID "@webcl.nokiaresearch.com/WebCLMemoryObject;1"
+
+/** Implements IWebCLMemoryObject interface. */
+class WebCLMemoryObject : public IWebCLMemoryObject, public WebCLCommon
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISECURITYCHECKEDCOMPONENT
+  NS_DECL_IWEBCLMEMORYOBJECT
+
+  static nsresult getInstance (cl_mem aInternal, WebCLMemoryObject** aResultOut,
+                               WebCL_LibCLWrapper* aLibWrapper = 0);
+
+  WebCLMemoryObject ();
+  cl_mem getInternal () { return mInternal; }
+
+protected:
+  int getTypeForInfoName (int aName);
+
+private:
+  static InstanceRegistry<cl_mem, WebCLMemoryObject*> instanceRegistry;
+
+  ~WebCLMemoryObject ();
+
+  cl_mem mInternal;
+};
+
+#endif // _WEBCL_MEMORYOBJECT_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCLObserver.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLObserver.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,63 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCLObserver.h"
+
+#include "WebCL.h"
+#include "WebCLLogger.h"
+
+#include <nsIVariant.h>
+#include <nsIObserver.h>
+
+NS_IMPL_ISUPPORTS1(WebCLObserver, nsIObserver)
+
+
+WebCLObserver::WebCLObserver ()
+  : nsIObserver(), mWebCL(0)
+{
+  D_METHOD_START;
+}
+
+WebCLObserver::~WebCLObserver ()
+{
+  D_METHOD_START;
+}
+
+void WebCLObserver::setWebCL (WebCL* aWebCL)
+{
+  mWebCL = aWebCL;
+}
+
+NS_IMETHODIMP WebCLObserver::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aData)
+{
+  D_LOG (LOG_LEVEL_DEBUG, "topic=%s%s", aTopic, mWebCL?"":"  WEBCL NOT SET!");
+
+  return (mWebCL ? (mWebCL->preferenceChanged (aSubject, aTopic, aData)) : NS_ERROR_FAILURE);
+}
+
diff -r 450143d2d810 browser/components/webcl/src/WebCLObserver.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLObserver.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,52 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef WEBCLOBSERVER_H
+#define WEBCLOBSERVER_H
+
+#include <nsIObserver.h>
+
+class WebCL;
+
+class WebCLObserver : public nsIObserver
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIOBSERVER
+
+  WebCLObserver ();
+
+  void setWebCL (WebCL* aWebCL);
+
+private:
+  virtual ~WebCLObserver ();
+  WebCL* mWebCL;
+};
+
+#endif // WEBCLOBSERVER_H
diff -r 450143d2d810 browser/components/webcl/src/WebCLPlatform.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLPlatform.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,167 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCLPlatform.h"
+#include "WebCLCommon.h"
+#include "WebCL_internal.h"
+#include "WebCL_clwrapper.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsISecurityCheckedComponent.h"
+#include "nsTArray.h"
+
+
+NS_IMPL_ISUPPORTS2 (WebCLPlatform, IWebCLPlatform, nsISecurityCheckedComponent)
+WEBCL_SECURITY_CHECKED_IMPL (WebCLPlatform)
+
+/* static */
+InstanceRegistry<cl_platform_id, WebCLPlatform*> WebCLPlatform::instanceRegistry;
+
+
+/* static */
+nsresult WebCLPlatform::getInstance (cl_platform_id aInternal, WebCLPlatform** aResultOut,
+                                     WebCL_LibCLWrapper* aLibWrapper)
+{
+  nsresult rv = NS_OK;
+
+  WebCLPlatform* existing = 0;
+  if (instanceRegistry.findById (aInternal, &existing))
+  {
+    NS_IF_ADDREF (*aResultOut = existing);
+  }
+  else
+  {
+    nsCOMPtr<WebCLPlatform> obj = do_CreateInstance (WEBCL_PLATFORM_CONTRACTID, &rv);
+    if (NS_FAILED (rv))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to create instance. rv=%d.", rv);
+      return rv;
+    }
+
+    obj->setWrapper (aLibWrapper);
+    obj->mInternal = aInternal;
+
+    instanceRegistry.add (obj->mInternal, obj);
+
+    NS_IF_ADDREF (*aResultOut = obj);
+  }
+
+  return rv;
+}
+
+
+WebCLPlatform::WebCLPlatform()
+  : IWebCLPlatform(), WebCLCommon(),
+    mInternal(0)
+{
+  D_METHOD_START;
+}
+
+
+WebCLPlatform::~WebCLPlatform()
+{
+  D_METHOD_START;
+  if (mInternal)
+    instanceRegistry.remove (mInternal);
+}
+
+
+int WebCLPlatform::getTypeForInfoName (int aName)
+{
+  D_METHOD_START;
+  switch (aName)
+  {
+    case CL_PLATFORM_PROFILE: return types::STRING;
+    case CL_PLATFORM_VERSION: return types::STRING;
+    case CL_PLATFORM_NAME: return types::STRING;
+    case CL_PLATFORM_VENDOR: return types::STRING;
+    case CL_PLATFORM_EXTENSIONS: return types::STRING;
+    default: ;
+  }
+  return types::UNKNOWN;
+}
+
+/* nsIVariant getPlatformInfo (in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLPlatform::GetPlatformInfo(PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  WEBCL_GETINFO_MEDIATOR_SWITCH (aName, type, mWrapper, getPlatformInfo, mInternal,
+                                 variant, err, rv);
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
+
+
+/* nsIVariant getDeviceIDs (in T_WebCLDeviceType aType); */
+NS_IMETHODIMP WebCLPlatform::GetDeviceIDs(T_WebCLDeviceType aType, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  return GetDevices (aType, cx, _retval);
+}
+
+
+/* nsIVariant getDevices (in T_WebCLDeviceType aType); */
+NS_IMETHODIMP WebCLPlatform::GetDevices(T_WebCLDeviceType aType, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsTArray<cl_device_id> devices;
+  cl_int err = mWrapper->getDeviceIDs (mInternal, aType, devices);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<nsIVariant> res;
+  rv = WebCL_convertVectorToJSArrayInVariant (cx, devices, types::DEVICE_V,
+                                              getter_AddRefs (res), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = res);
+  return NS_OK;
+}
+
+
diff -r 450143d2d810 browser/components/webcl/src/WebCLPlatform.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLPlatform.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,69 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCLPLATFORM_H_
+#define _WEBCLPLATFORM_H_
+
+#include "WebCLCommon.h"
+#include "IWebCLPlatform.h" // Generated from IWebCLPlatform.idl
+#include "instance_registry.h"
+
+#include <CL/opencl.h>
+
+
+#define WEBCL_PLATFORM_CLASSNAME "WebCLPlatform"
+#define WEBCL_PLATFORM_CID { 0x6ab8b8cf, 0x4d87, 0x40a0, { 0xaf, 0x8a, 0xcc, 0x0b, 0xf5, 0x25, 0x1f, 0xa3 } }
+#define WEBCL_PLATFORM_CONTRACTID "@webcl.nokiaresearch.com/WebCLPlatform;1"
+
+/** Implements IWebCLPlatform interface. */
+class WebCLPlatform : public IWebCLPlatform, public WebCLCommon
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISECURITYCHECKEDCOMPONENT
+  NS_DECL_IWEBCLPLATFORM
+
+  static nsresult getInstance (cl_platform_id aInternal, WebCLPlatform** aResultOut,
+                               WebCL_LibCLWrapper* aLibWrapper = 0);
+
+  WebCLPlatform ();
+  cl_platform_id getInternal () { return mInternal; }
+
+protected:
+  int getTypeForInfoName (int aName);
+
+private:
+  static InstanceRegistry<cl_platform_id, WebCLPlatform*> instanceRegistry;
+
+  ~WebCLPlatform ();
+
+  cl_platform_id mInternal;
+};
+
+#endif //_WEBCLPLATFORM_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCLProgram.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLProgram.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,324 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCLProgram.h"
+#include "WebCLCommon.h"
+#include "WebCL_internal.h"
+#include "WebCL_clwrapper.h"
+#include "WebCLPlatform.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsISecurityCheckedComponent.h"
+
+
+NS_IMPL_ISUPPORTS2 (WebCLProgram, IWebCLProgram, nsISecurityCheckedComponent)
+WEBCL_SECURITY_CHECKED_IMPL (WebCLProgram)
+
+
+/* static */
+InstanceRegistry<cl_program, WebCLProgram*> WebCLProgram::instanceRegistry;
+
+
+/* static */
+nsresult WebCLProgram::getInstance (cl_program aInternal, WebCLProgram** aResultOut,
+                                    WebCL_LibCLWrapper* aLibWrapper)
+{
+  nsresult rv = NS_OK;
+
+  WebCLProgram* existing = 0;
+  if (instanceRegistry.findById (aInternal, &existing))
+  {
+    NS_IF_ADDREF (*aResultOut = existing);
+  }
+  else
+  {
+    nsCOMPtr<WebCLProgram> obj = do_CreateInstance (WEBCL_PROGRAM_CONTRACTID, &rv);
+    if (NS_FAILED (rv))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to create instance. rv=%d.", rv);
+      return rv;
+    }
+
+    obj->setWrapper (aLibWrapper);
+    obj->mInternal = aInternal;
+
+    instanceRegistry.add (obj->mInternal, obj);
+
+    NS_IF_ADDREF (*aResultOut = obj);
+  }
+
+  return rv;
+}
+
+
+WebCLProgram::WebCLProgram()
+  : IWebCLProgram(), WebCLCommon(),
+    mInternal(0)
+{
+  D_METHOD_START;
+}
+
+
+WebCLProgram::~WebCLProgram()
+{
+  D_METHOD_START;
+  if (mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (mWrapper)
+      mWrapper->releaseProgram (mInternal);
+    mInternal = 0;
+  }
+}
+
+
+int WebCLProgram::getTypeForInfoName (int aName)
+{
+  D_METHOD_START;
+  switch (aName)
+  {
+    // getInfo names
+    case CL_PROGRAM_REFERENCE_COUNT: return types::UINT;
+    case CL_PROGRAM_CONTEXT: return types::CONTEXT;
+    case CL_PROGRAM_NUM_DEVICES: return types::UINT;
+    case CL_PROGRAM_DEVICES: return types::DEVICE_V;
+    case CL_PROGRAM_SOURCE: return types::STRING;
+    case CL_PROGRAM_BINARY_SIZES: return types::SIZE_T_V;
+    case CL_PROGRAM_BINARIES: return types::STRING_V;
+
+    // getBuildInfo names
+    case CL_PROGRAM_BUILD_STATUS: return types::BUILD_STATUS;
+    case CL_PROGRAM_BUILD_OPTIONS: return types::STRING;
+    case CL_PROGRAM_BUILD_LOG: return types::STRING;
+
+    default: ;
+  }
+  return types::UNKNOWN;
+}
+
+
+/* nsIVariant getProgramInfo (in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLProgram::GetProgramInfo(PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  // TODO NOTE CL_PROGRAM_BINARIES WORKAROUND - THIS PARAMETER SHOULD PROBABLY BE BLOCKED
+  if (aName == CL_PROGRAM_BINARIES)
+  {
+    // CL_PROGRAM_BINARIES does not write it's result directly to the target buffer
+    // but to an array pointers to additional buffers of allocated by caller. The sizes
+    // of these buffers are queried using CL_PROGRAM_BINARY_SIZES
+    nsTArray<size_t> binarySizes;
+    mWrapper->getProgramInfo (mInternal, CL_PROGRAM_BINARY_SIZES, binarySizes);
+    nsTArray<char*> binaries;
+    binaries.SetLength (binarySizes.Length());
+    for (size_t i = 0; i < binaries.Length(); ++i)
+    {
+      binaries[i] = (char*)malloc(sizeof(char) * binarySizes[i]);
+      // Allocation failures produce NULL and we expect that OCL library knows
+      // how to handle that.
+    }
+
+    err = mWrapper->library()->symbols->clGetProgramInfo (mInternal, CL_PROGRAM_BINARIES,
+                                                          sizeof(char*) * binaries.Length(),
+                                                          binaries.Elements(), NULL);
+    if (CL_FAILED (err))
+    {
+      for (nsTArray<char*>::index_type i = 0; i < binaries.Length(); ++i)
+      {
+        free (binaries[i]);
+      }
+      D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+      WebCL_reportJSError (cx, "%s failed with error %d.", __FUNCTION__, err);
+      return WEBCL_XPCOM_ERROR; /*NS_ERROR_FAILURE;*/
+    }
+
+    // Convert result to something we can apply our standard mechanism to
+    nsTArray<nsCString> results;
+    results.SetCapacity (binaries.Length());
+    for (size_t i = 0; i < binaries.Length(); ++i)
+    {
+      results.AppendElement (nsCString(binaries[i]));
+      free (binaries[i]);
+    }
+
+    rv = WebCL_convertVectorToJSArrayInVariant (cx, results, types::STRING_V,
+                                                (nsIVariant**)&variant, mWrapper);
+    NS_ENSURE_SUCCESS (rv, rv);
+  }
+  else
+  {
+    WEBCL_GETINFO_MEDIATOR_SWITCH (aName, type, mWrapper, getProgramInfo, mInternal,
+                                   variant, err, rv);
+  }
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
+
+
+/* nsIVariant getProgramBuildInfo (in nsISupports aDevice, in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLProgram::GetProgramBuildInfo(nsISupports* aDevice, PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+
+  NS_ENSURE_ARG_POINTER (aDevice);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<WebCLDevice> device = do_QueryInterface (aDevice, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  WEBCL_GETINFO_MEDIATOR_EXTRA_SWITCH (device->getInternal(), aName, type,
+                                       mWrapper, getProgramBuildInfo, mInternal,
+                                       variant, err, rv);
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
+
+
+/* void buildProgram (in nsIVariant aDevices, in string aOptions); */
+NS_IMETHODIMP WebCLProgram::BuildProgram(nsIVariant *aDevices, const char *aOptions, JSContext *cx)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aDevices);
+  NS_ENSURE_ARG_POINTER (cx);
+  nsresult rv;
+
+  nsTArray<nsIVariant*> deviceVariants;
+  rv = WebCL_getVariantsFromJSArray (cx, aDevices, deviceVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  nsTArray<cl_device_id> devices;
+  rv = WebCL_convertVariantVectorToInternalVector<WebCLDevice, cl_device_id> (deviceVariants,
+                                                                              devices);
+  WebCL_releaseVariantVector (deviceVariants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  cl_int err = mWrapper->buildProgram (mInternal, devices, nsCString(aOptions), 0, 0);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  return NS_OK;
+}
+
+
+/* IWebCLKernel createKernel (in string aKernelName); */
+NS_IMETHODIMP WebCLProgram::CreateKernel(const char *aKernelName, JSContext *cx, IWebCLKernel **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  cl_int err = CL_SUCCESS;
+  cl_kernel kernel = mWrapper->createKernel (mInternal, nsCString(aKernelName), &err);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<WebCLKernel> xpcObj;
+  rv = WebCLKernel::getInstance (kernel, getter_AddRefs(xpcObj), mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = xpcObj);
+
+  return NS_OK;
+}
+
+
+/* nsIVariant createKernelsInProgram (); */
+NS_IMETHODIMP WebCLProgram::CreateKernelsInProgram(JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+
+  nsTArray<cl_kernel> kernels;
+  cl_int err = mWrapper->createKernelsInProgram (mInternal, kernels);
+  ENSURE_LIB_WRAPPER_SUCCESS (mWrapper);
+  ENSURE_CL_OP_SUCCESS (err);
+
+  nsCOMPtr<nsIVariant> value;
+  rv = WebCL_convertVectorToJSArrayInVariant (cx, kernels,
+                                              types::KERNEL_V,
+                                              getter_AddRefs (value),
+                                              mWrapper);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*_retval = value);
+
+  return NS_OK;
+}
+
+
+/* void releaseCLResources (); */
+NS_IMETHODIMP WebCLProgram::ReleaseCLResources ()
+{
+  D_METHOD_START;
+  if (mWrapper && mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (CL_FAILED (mWrapper->releaseProgram (mInternal)))
+      D_LOG (LOG_LEVEL_WARNING, "Failed to release CL resources.");
+    mInternal = 0;
+  }
+  mWrapper = 0;
+  return NS_OK;
+}
diff -r 450143d2d810 browser/components/webcl/src/WebCLProgram.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLProgram.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,69 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCLPROGRAM_H_
+#define _WEBCLPROGRAM_H_
+
+#include "WebCLCommon.h"
+#include "IWebCLProgram.h" // Generated from IWebCLProgram.idl
+#include "instance_registry.h"
+
+#include <CL/opencl.h>
+
+
+#define WEBCL_PROGRAM_CLASSNAME "WebCLProgram"
+#define WEBCL_PROGRAM_CID { 0x74d49a1e, 0x31e0, 0x41d5, { 0x8e, 0x98, 0x89, 0x80, 0xa0, 0x77, 0xfc, 0xb2 } }
+#define WEBCL_PROGRAM_CONTRACTID "@webcl.nokiaresearch.com/WebCLProgram;1"
+
+/** Implements IWebCLProgram interface. */
+class WebCLProgram : public IWebCLProgram, public WebCLCommon
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISECURITYCHECKEDCOMPONENT
+  NS_DECL_IWEBCLPROGRAM
+
+  static nsresult getInstance (cl_program aInternal, WebCLProgram** aResultOut,
+                               WebCL_LibCLWrapper* aLibWrapper = 0);
+
+  WebCLProgram ();
+  cl_program getInternal () { return mInternal; }
+
+protected:
+  int getTypeForInfoName (int aName);
+
+private:
+  static InstanceRegistry<cl_program, WebCLProgram*> instanceRegistry;
+
+  ~WebCLProgram ();
+
+  cl_program mInternal;
+};
+
+#endif //_WEBCLPROGRAM_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCLSampler.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLSampler.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,158 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCLSampler.h"
+#include "WebCLCommon.h"
+#include "WebCL_internal.h"
+#include "WebCL_clwrapper.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsISecurityCheckedComponent.h"
+
+
+NS_IMPL_ISUPPORTS2 (WebCLSampler, IWebCLSampler, nsISecurityCheckedComponent)
+WEBCL_SECURITY_CHECKED_IMPL (WebCLSampler)
+
+
+/* static */
+InstanceRegistry<cl_sampler, WebCLSampler*> WebCLSampler::instanceRegistry;
+
+
+/* static */
+nsresult WebCLSampler::getInstance (cl_sampler aInternal, WebCLSampler** aResultOut,
+                                    WebCL_LibCLWrapper* aLibWrapper)
+{
+  nsresult rv = NS_OK;
+
+  WebCLSampler* existing = 0;
+  if (instanceRegistry.findById (aInternal, &existing))
+  {
+    NS_IF_ADDREF (*aResultOut = existing);
+  }
+  else
+  {
+    nsCOMPtr<WebCLSampler> obj = do_CreateInstance (WEBCL_SAMPLER_CONTRACTID, &rv);
+    if (NS_FAILED (rv))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to create instance. rv=%d.", rv);
+      return rv;
+    }
+
+    obj->setWrapper (aLibWrapper);
+    obj->mInternal = aInternal;
+
+    instanceRegistry.add (obj->mInternal, obj);
+
+    NS_IF_ADDREF (*aResultOut = obj);
+  }
+
+  return rv;
+}
+
+
+WebCLSampler::WebCLSampler()
+  : IWebCLSampler(), WebCLCommon(),
+    mInternal(0)
+{
+  D_METHOD_START;
+}
+
+
+WebCLSampler::~WebCLSampler()
+{
+  D_METHOD_START;
+  if (mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (mWrapper)
+      mWrapper->releaseSampler (mInternal);
+    mInternal = 0;
+  }
+}
+
+
+int WebCLSampler::getTypeForInfoName (int aName)
+{
+  D_METHOD_START;
+  switch (aName)
+  {
+    case CL_SAMPLER_REFERENCE_COUNT: return types::UINT;
+    case CL_SAMPLER_CONTEXT: return types::CONTEXT;
+    case CL_SAMPLER_ADDRESSING_MODE: return types::ADRESSING_MODE;
+    case CL_SAMPLER_FILTER_MODE: return types::FILTER_MODE;
+    case CL_SAMPLER_NORMALIZED_COORDS: return types::BOOL;
+    default: ;
+  }
+  return types::UNKNOWN;
+}
+
+
+/* nsIVariant getSamplerInfo (in long aName, [optional] in long aType); */
+NS_IMETHODIMP WebCLSampler::GetSamplerInfo(PRInt32 aName, PRInt32, JSContext *cx, nsIVariant **_retval NS_OUTPARAM)
+{
+  D_METHOD_START;
+
+  NS_ENSURE_ARG_POINTER (_retval);
+  nsresult rv;
+  cl_int err = CL_SUCCESS;
+  int type = getTypeForInfoName (aName);
+  if (type == types::UNKNOWN)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Info parameter name %d does not have a known type.", aName);
+    WebCL_reportJSError (cx, "Info name %d is not supported by %s.",
+                         aName, __FUNCTION__);
+    return WEBCL_XPCOM_ERROR; //NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  WEBCL_GETINFO_MEDIATOR_SWITCH (aName, type, mWrapper, getSamplerInfo, mInternal,
+                                 variant, err, rv);
+
+  NS_ADDREF (*_retval = variant);
+
+  return NS_OK;
+}
+
+
+/* void releaseCLResources (); */
+NS_IMETHODIMP WebCLSampler::ReleaseCLResources ()
+{
+  D_METHOD_START;
+  if (mWrapper && mInternal)
+  {
+    instanceRegistry.remove (mInternal);
+    if (CL_FAILED (mWrapper->releaseSampler (mInternal)))
+      D_LOG (LOG_LEVEL_WARNING, "Failed to release CL resources.");
+    mInternal = 0;
+  }
+  mWrapper = 0;
+  return NS_OK;
+}
diff -r 450143d2d810 browser/components/webcl/src/WebCLSampler.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCLSampler.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,69 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCLSAMPLER_H_
+#define _WEBCLSAMPLER_H_
+
+#include "WebCLCommon.h"
+#include "IWebCLSampler.h" // Generated from IWebCLSampler.idl
+#include "instance_registry.h"
+
+#include <CL/opencl.h>
+
+
+#define WEBCL_SAMPLER_CLASSNAME "WebCLSampler"
+#define WEBCL_SAMPLER_CID { 0xdc9b25aa, 0x2bdc, 0x4efd, { 0xb2, 0x95, 0xb4, 0x50, 0xc7, 0x5d, 0x25, 0x2c } }
+#define WEBCL_SAMPLER_CONTRACTID "@webcl.nokiaresearch.com/WebCLSampler;1"
+
+/** Implements IWebCLSampler interface. */
+class WebCLSampler : public IWebCLSampler, public WebCLCommon
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISECURITYCHECKEDCOMPONENT
+  NS_DECL_IWEBCLSAMPLER
+
+  static nsresult getInstance (cl_sampler aInternal, WebCLSampler** aResultOut,
+                               WebCL_LibCLWrapper* aLibWrapper = 0);
+
+  WebCLSampler ();
+  cl_sampler getInternal () { return mInternal; }
+
+protected:
+  int getTypeForInfoName (int aName);
+
+private:
+  static InstanceRegistry<cl_sampler, WebCLSampler*> instanceRegistry;
+
+  ~WebCLSampler ();
+
+  cl_sampler mInternal;
+};
+
+#endif //_WEBCLSAMPLER_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCL_clsymbols.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCL_clsymbols.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,133 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCL_CLSYMBOLS_H_
+#define _WEBCL_CLSYMBOLS_H_
+
+#include "CL/opencl.h"
+
+
+#define WEBCL_LIB_CL_ENTRY(retval_t,name,...) \
+typedef retval_t (CL_API_CALL * _##name##_t)(__VA_ARGS__); \
+retval_t (CL_API_CALL * name)(__VA_ARGS__)
+
+struct WebCL_CLSymbols
+{
+  // OpenCL 1.1 API
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetPlatformIDs, cl_uint, cl_platform_id*, cl_uint*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetPlatformInfo, cl_platform_id, cl_platform_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetDeviceIDs, cl_platform_id, cl_device_type, cl_uint, cl_device_id*, cl_uint*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetDeviceInfo, cl_device_id, cl_device_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_context, clCreateContext, const cl_context_properties*, cl_uint, const cl_device_id*, void (CL_CALLBACK* )(const char*, const void*, size_t, void*), void*, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_context, clCreateContextFromType, const cl_context_properties*, cl_device_type, void (CL_CALLBACK* )(const char*, const void*, size_t, void*), void*, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clRetainContext, cl_context);
+  WEBCL_LIB_CL_ENTRY(cl_int, clReleaseContext, cl_context);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetContextInfo, cl_context, cl_context_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_command_queue, clCreateCommandQueue, cl_context, cl_device_id, cl_command_queue_properties, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clRetainCommandQueue, cl_command_queue);
+  WEBCL_LIB_CL_ENTRY(cl_int, clReleaseCommandQueue, cl_command_queue);
+  WEBCL_LIB_CL_ENTRY(cl_int, clSetCommandQueueProperty, cl_command_queue aCmdQueue, cl_command_queue_properties aProperties, cl_bool aEnable, cl_command_queue_properties* aOldProperties);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetCommandQueueInfo, cl_command_queue, cl_command_queue_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_mem, clCreateBuffer, cl_context, cl_mem_flags, size_t, void*, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_mem, clCreateSubBuffer, cl_mem, cl_mem_flags, cl_buffer_create_type, const void*, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_mem, clCreateImage2D, cl_context, cl_mem_flags, const cl_image_format*, size_t, size_t, size_t, void*, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_mem, clCreateImage3D, cl_context, cl_mem_flags, const cl_image_format*, size_t, size_t, size_t, size_t, size_t, void*, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clRetainMemObject, cl_mem);
+  WEBCL_LIB_CL_ENTRY(cl_int, clReleaseMemObject, cl_mem);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetSupportedImageFormats, cl_context, cl_mem_flags, cl_mem_object_type, cl_uint, cl_image_format*, cl_uint*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetMemObjectInfo, cl_mem, cl_mem_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetImageInfo, cl_mem, cl_image_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clSetMemObjectDestructorCallback, cl_mem, void (CL_CALLBACK* )( cl_mem, void* ), void*);
+  WEBCL_LIB_CL_ENTRY(cl_sampler, clCreateSampler, cl_context, cl_bool, cl_addressing_mode, cl_filter_mode, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clRetainSampler, cl_sampler);
+  WEBCL_LIB_CL_ENTRY(cl_int, clReleaseSampler, cl_sampler);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetSamplerInfo, cl_sampler, cl_sampler_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_program, clCreateProgramWithSource, cl_context, cl_uint, const char**, const size_t*, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_program, clCreateProgramWithBinary, cl_context, cl_uint, const cl_device_id*, const size_t*, const unsigned char**, cl_int*, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clRetainProgram, cl_program);
+  WEBCL_LIB_CL_ENTRY(cl_int, clReleaseProgram, cl_program);
+  WEBCL_LIB_CL_ENTRY(cl_int, clBuildProgram, cl_program, cl_uint, const cl_device_id*, const char*, void (CL_CALLBACK* )(cl_program, void* ), void*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clUnloadCompiler, void);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetProgramInfo, cl_program, cl_program_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetProgramBuildInfo, cl_program, cl_device_id, cl_program_build_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_kernel, clCreateKernel, cl_program, const char*, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clCreateKernelsInProgram, cl_program, cl_uint, cl_kernel*, cl_uint*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clRetainKernel, cl_kernel);
+  WEBCL_LIB_CL_ENTRY(cl_int, clReleaseKernel, cl_kernel);
+  WEBCL_LIB_CL_ENTRY(cl_int, clSetKernelArg, cl_kernel, cl_uint, size_t, const void*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetKernelInfo, cl_kernel, cl_kernel_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetKernelWorkGroupInfo, cl_kernel, cl_device_id, cl_kernel_work_group_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clWaitForEvents, cl_uint, const cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetEventInfo, cl_event, cl_event_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_event, clCreateUserEvent, cl_context, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clRetainEvent, cl_event);
+  WEBCL_LIB_CL_ENTRY(cl_int, clReleaseEvent, cl_event);
+  WEBCL_LIB_CL_ENTRY(cl_int, clSetUserEventStatus, cl_event, cl_int);
+  WEBCL_LIB_CL_ENTRY(cl_int, clSetEventCallback, cl_event, cl_int, void (CL_CALLBACK* )(cl_event, cl_int, void*), void*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetEventProfilingInfo, cl_event, cl_profiling_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clFlush, cl_command_queue);
+  WEBCL_LIB_CL_ENTRY(cl_int, clFinish, cl_command_queue);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueReadBuffer, cl_command_queue, cl_mem, cl_bool, size_t, size_t, void*, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueReadBufferRect, cl_command_queue, cl_mem, cl_bool, const size_t*, const size_t*, const size_t*, size_t, size_t, size_t, size_t, void*, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueWriteBuffer, cl_command_queue, cl_mem, cl_bool, size_t, size_t, const void*, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueWriteBufferRect, cl_command_queue, cl_mem, cl_bool, const size_t*, const size_t*, const size_t*, size_t, size_t, size_t, size_t, const void*, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueCopyBuffer, cl_command_queue, cl_mem, cl_mem, size_t, size_t, size_t, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueCopyBufferRect, cl_command_queue, cl_mem, cl_mem, const size_t*, const size_t*, const size_t*, size_t, size_t, size_t, size_t, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueReadImage, cl_command_queue, cl_mem, cl_bool, const size_t*, const size_t*, size_t, size_t, void*, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueWriteImage, cl_command_queue, cl_mem, cl_bool, const size_t*, const size_t*, size_t, size_t, const void*, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueCopyImage, cl_command_queue, cl_mem, cl_mem, const size_t*, const size_t*, const size_t*, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueCopyImageToBuffer, cl_command_queue, cl_mem, cl_mem, const size_t*, const size_t*, size_t, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueCopyBufferToImage, cl_command_queue, cl_mem, cl_mem, size_t, const size_t*, const size_t*, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(void*, clEnqueueMapBuffer, cl_command_queue, cl_mem, cl_bool, cl_map_flags, size_t, size_t, cl_uint, const cl_event*, cl_event*, cl_int*);
+  WEBCL_LIB_CL_ENTRY(void*, clEnqueueMapImage, cl_command_queue, cl_mem, cl_bool, cl_map_flags, const size_t*, const size_t*, size_t*, size_t*, cl_uint, const cl_event*, cl_event*, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueUnmapMemObject, cl_command_queue, cl_mem, void*, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueNDRangeKernel, cl_command_queue, cl_kernel, cl_uint, const size_t*, const size_t*, const size_t*, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueTask, cl_command_queue, cl_kernel, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueNativeKernel, cl_command_queue, void (*user_func)(void*), void*, size_t, cl_uint, const cl_mem*, const void**, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueMarker, cl_command_queue, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueWaitForEvents, cl_command_queue, cl_uint, const cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueBarrier, cl_command_queue);
+  WEBCL_LIB_CL_ENTRY(void*, clGetExtensionFunctionAddress, const char*);
+
+  // OpenCL 1.1 OpenGL interoperability API
+  WEBCL_LIB_CL_ENTRY(cl_mem, clCreateFromGLBuffer, cl_context, cl_mem_flags, cl_GLuint, int*);
+  WEBCL_LIB_CL_ENTRY(cl_mem, clCreateFromGLTexture2D, cl_context, cl_mem_flags, cl_GLenum, cl_GLint, cl_GLuint, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_mem, clCreateFromGLTexture3D, cl_context, cl_mem_flags, cl_GLenum, cl_GLint, cl_GLuint, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_mem, clCreateFromGLRenderbuffer, cl_context, cl_mem_flags, cl_GLuint, cl_int*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetGLObjectInfo, cl_mem, cl_gl_object_type*, cl_GLuint*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetGLTextureInfo, cl_mem, cl_gl_texture_info, size_t, void*, size_t*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueAcquireGLObjects, cl_command_queue, cl_uint, const cl_mem*, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clEnqueueReleaseGLObjects, cl_command_queue, cl_uint, const cl_mem*, cl_uint, const cl_event*, cl_event*);
+  WEBCL_LIB_CL_ENTRY(cl_int, clGetGLContextInfoKHR, const cl_context_properties*, cl_gl_context_info, size_t, void*, size_t*);
+
+  // Loader impl. specific!
+  void* libHandle;
+};
+
+#endif //_WEBCL_CLSYMBOLS_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCL_clwrapper.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCL_clwrapper.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,1512 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCL_clwrapper.h"
+#include "WebCL_libcl.h"
+#include "WebCL_clsymbols.h"
+
+
+#define WCLLIB_ERR_NO_INFOFUNC "Invalid infoFunc argument (null)."
+
+#define VALIDATE_INFOFUNC() do{\
+    if (!infoFunc) { \
+      D_LOG (LOG_LEVEL_ERROR, WCLLIB_ERR_NO_INFOFUNC); \
+      return CL_INVALID_VALUE; \
+    }}while(0)
+
+cl_int WebCLLibWrapperDetail::getInfoImpl_string (clobject aInstance, int aName, nsCString& aValueOut, InfoFunc infoFunc)
+{
+    D_METHOD_START;
+    cl_int err = CL_SUCCESS;
+    char* buf = 0;
+    size_t sze = 0;
+    VALIDATE_INFOFUNC ();
+    err = infoFunc (aInstance, aName, 0, 0, &sze);
+    if (err != CL_SUCCESS)
+    {
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+        return err;
+    }
+    buf = (char*)malloc (sizeof (char) * (sze + 1));
+    if (!buf)
+    {
+        D_LOG (LOG_LEVEL_ERROR, "Memory allocation failed.");
+        return CL_OUT_OF_HOST_MEMORY;
+    }
+    err = infoFunc (aInstance, aName, sze, (void*)buf, 0);
+    if (err != CL_SUCCESS)
+    {
+        free (buf);
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+        return err;
+    }
+    buf[sze] = '\0'; // Just to be safe..
+    aValueOut = buf;
+    free (buf);
+    return err;
+}
+
+
+cl_int WebCLLibWrapperDetail::getInfoImpl_string_V (clobject aInstance, int aName, nsTArray<nsCString>& aValueOut, InfoFunc infoFunc)
+{
+    D_METHOD_START;
+    char** buf = 0;
+    size_t sze = 0;
+    cl_int err = CL_SUCCESS;
+    VALIDATE_INFOFUNC ();
+    err = infoFunc (aInstance, aName, 0, 0, &sze);
+    if (err != CL_SUCCESS)
+    {
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+        return err;
+    }
+    buf = (char**)malloc (sze);
+    if (!buf)
+    {
+        D_LOG (LOG_LEVEL_ERROR, "Memory allocation failed.");
+        return CL_OUT_OF_HOST_MEMORY;
+    }
+
+    err = infoFunc (aInstance, aName, sze, (void*)buf, 0);
+    if (err != CL_SUCCESS)
+    {
+        free (buf);
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+        return err;
+    }
+    aValueOut.Clear ();
+    size_t num = sze / sizeof (char*);
+    aValueOut.SetLength (num);
+    for (size_t i = 0; i < num; ++i)
+        aValueOut.AppendElement (nsCString (buf[i]));
+    free (buf);
+    return err;
+}
+
+
+cl_int WebCLLibWrapperDetail::getInfoImpl_ImageFormat (clobject aInstance, int aName, cl_image_format& aValueOut, InfoFunc infoFunc)
+{
+    D_METHOD_START;
+    cl_int err = CL_SUCCESS;
+    cl_image_format buf;
+    size_t sze = 0;
+    VALIDATE_INFOFUNC ();
+    err = infoFunc (aInstance, aName, sizeof(buf), (void*)&buf, &sze);
+    if (err != CL_SUCCESS)
+    {
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+        return err;
+    }
+    if (sizeof(buf) != sze)
+    {
+        D_LOG (LOG_LEVEL_ERROR,
+             "getInfo returned a value of unexpected size %u, expected (%u bytes)",
+             sze, sizeof(buf));
+        return CL_INVALID_VALUE;
+    }
+    aValueOut = buf;
+    return err;
+}
+
+
+#define IMPL_GET_INFO_FOR_OBJECT(name,clType) \
+cl_int WebCLLibWrapperDetail::getInfoImpl_##name (clobject aInstance, int aName, clType& aValueOut, InfoFunc infoFunc) { \
+    D_METHOD_START; \
+    cl_int err = CL_SUCCESS; \
+    size_t sze = 0; \
+    clType clHandle = 0; \
+    VALIDATE_INFOFUNC (); \
+    err = infoFunc (aInstance, aName, sizeof(clType), (void*)&clHandle, &sze); \
+    if (err != CL_SUCCESS) { \
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err); \
+        return err; \
+    } \
+    if (sze != sizeof(clType)) { \
+        D_LOG (LOG_LEVEL_ERROR, \
+             "getInfo returned a value of unexpected size %u, expected (%u bytes)", \
+             sze, sizeof(clType)); \
+        return CL_INVALID_VALUE; \
+    } \
+    aValueOut = clHandle; \
+    return err; \
+}
+
+IMPL_GET_INFO_FOR_OBJECT (Platform, cl_platform_id)
+IMPL_GET_INFO_FOR_OBJECT (Device, cl_device_id)
+IMPL_GET_INFO_FOR_OBJECT (Context, cl_context)
+IMPL_GET_INFO_FOR_OBJECT (Event, cl_event)
+IMPL_GET_INFO_FOR_OBJECT (CommandQueue, cl_command_queue)
+IMPL_GET_INFO_FOR_OBJECT (MemoryObject, cl_mem)
+IMPL_GET_INFO_FOR_OBJECT (Program, cl_program)
+IMPL_GET_INFO_FOR_OBJECT (Kernel, cl_kernel)
+IMPL_GET_INFO_FOR_OBJECT (Sampler, cl_sampler)
+
+
+
+#define IMPL_GET_INFO_FOR_OBJECT_VECTOR(name,clType) \
+cl_int WebCLLibWrapperDetail::getInfoImpl_##name##_V (clobject aInstance, int aName, nsTArray<clType>& aValueOut, InfoFunc infoFunc) { \
+    D_METHOD_START; \
+    size_t sze = 0; \
+    cl_int err = CL_SUCCESS; \
+    VALIDATE_INFOFUNC (); \
+    err = infoFunc (aInstance, aName, 0, 0, &sze); \
+    if (err != CL_SUCCESS) { \
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err); \
+        return err; \
+    } \
+    nsTArray<clType> buf; \
+    buf.SetLength (sze / sizeof(clType)); /* TODO: check success */ \
+    err = infoFunc (aInstance, aName, sze, (void*)buf.Elements(), 0); \
+    if (err != CL_SUCCESS) { \
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err); \
+        return err; \
+    } \
+    aValueOut.SwapElements (buf); \
+    return err; \
+}
+
+IMPL_GET_INFO_FOR_OBJECT_VECTOR (Platform, cl_platform_id)
+IMPL_GET_INFO_FOR_OBJECT_VECTOR (Device, cl_device_id)
+IMPL_GET_INFO_FOR_OBJECT_VECTOR (Context, cl_context)
+IMPL_GET_INFO_FOR_OBJECT_VECTOR (Event, cl_event)
+IMPL_GET_INFO_FOR_OBJECT_VECTOR (CommandQueue, cl_command_queue)
+IMPL_GET_INFO_FOR_OBJECT_VECTOR (MemoryObject, cl_mem)
+IMPL_GET_INFO_FOR_OBJECT_VECTOR (Program, cl_program)
+IMPL_GET_INFO_FOR_OBJECT_VECTOR (Kernel, cl_kernel)
+IMPL_GET_INFO_FOR_OBJECT_VECTOR (Sampler, cl_sampler)
+
+
+cl_int WebCLLibWrapperDetail::getInfoImpl_string (clobject aInstance, clobject aExtra, int aName, nsCString& aValueOut, InfoFuncExtra infoFunc)
+{
+    D_METHOD_START;
+    cl_int err = CL_SUCCESS;
+    char* buf = 0;
+    size_t sze = 0;
+    VALIDATE_INFOFUNC ();
+    err = infoFunc (aInstance, aExtra, aName, 0, 0, &sze);
+    if (err != CL_SUCCESS)
+    {
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+        return err;
+    }
+    buf = (char*)malloc (sizeof (char) * (sze + 1));
+    if (!buf)
+    {
+        D_LOG (LOG_LEVEL_ERROR, "Memory allocation failed.");
+        return CL_OUT_OF_HOST_MEMORY;
+    }
+    err = infoFunc (aInstance, aExtra, aName, sze, (void*)buf, 0);
+    if (err != CL_SUCCESS)
+    {
+        free (buf);
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+        return err;
+    }
+    buf[sze] = '\0'; // Just to be safe..
+    aValueOut = buf;
+    free (buf);
+    return err;
+}
+
+cl_int WebCLLibWrapperDetail::getInfoImpl_string_V (clobject aInstance, clobject aExtra, int aName, nsTArray<nsCString>& aValueOut, InfoFuncExtra infoFunc)
+{
+    D_METHOD_START;
+    char** buf = 0;
+    size_t sze = 0;
+    VALIDATE_INFOFUNC ();
+    cl_int err = infoFunc (aInstance, aExtra, aName, 0, 0, &sze);
+    if (err != CL_SUCCESS)
+    {
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+        return err;
+    }
+    buf = (char**)malloc (sze);
+    if (!buf)
+    {
+        D_LOG (LOG_LEVEL_ERROR, "Memory allocation failed.");
+        return CL_OUT_OF_HOST_MEMORY;
+    }
+    err = infoFunc (aInstance, aExtra, aName, sze, (void*)buf, 0);
+    if (err != CL_SUCCESS)
+    {
+        free (buf);
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+        return err;
+    }
+    aValueOut.Clear ();
+    size_t num = sze / sizeof (char*);
+    aValueOut.SetLength (num);
+    for (size_t i = 0; i < num; ++i)
+    {
+        aValueOut.AppendElement (nsCString (buf[i]));
+    }
+    free (buf);
+    return err;
+}
+
+
+#define IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT(name,clType) \
+cl_int WebCLLibWrapperDetail::getInfoImpl_##name (clobject aInstance, clobject aExtra, int aName, clType& aValueOut, InfoFuncExtra infoFunc) { \
+    D_METHOD_START; \
+    cl_int err = CL_SUCCESS; \
+    size_t sze = 0; \
+    clType clHandle = 0; \
+    VALIDATE_INFOFUNC (); \
+    err = infoFunc (aInstance, aExtra, aName, sizeof(clType), (void*)&clHandle, &sze); \
+    if (err != CL_SUCCESS) { \
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err); \
+        return err; \
+    } \
+    if (sze != sizeof(clType)) { \
+        D_LOG (LOG_LEVEL_ERROR, \
+             "getInfo returned a value of unexpected size %u, expected (%u bytes)", \
+             sze, sizeof(clType)); \
+        return CL_INVALID_VALUE; \
+    } \
+    aValueOut = clHandle; \
+    return err; \
+}
+
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT (Platform, cl_platform_id)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT (Device, cl_device_id)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT (Context, cl_context)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT (Event, cl_event)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT (CommandQueue, cl_command_queue)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT (MemoryObject, cl_mem)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT (Program, cl_program)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT (Kernel, cl_kernel)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT (Sampler, cl_sampler)
+
+
+#define IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT_VECTOR(name,clType) \
+cl_int WebCLLibWrapperDetail::getInfoImpl_##name##_V (clobject aInstance, clobject aExtra, int aName, nsTArray<clType>& aValueOut, InfoFuncExtra infoFunc) { \
+    D_METHOD_START; \
+    cl_int err = CL_SUCCESS; \
+    size_t sze = 0; \
+    VALIDATE_INFOFUNC (); \
+    err = infoFunc (aInstance, aExtra, aName, 0, 0, &sze); \
+    if (err != CL_SUCCESS) { \
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err); \
+        return err; \
+    } \
+    nsTArray<clType> buf; \
+    buf.SetLength (sze / sizeof(clType)); /* TODO: check success */ \
+    err = infoFunc (aInstance, aExtra, aName, sze, (void*)buf.Elements(), 0); \
+    if (err != CL_SUCCESS) { \
+        D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err); \
+        return err; \
+    } \
+    aValueOut.SwapElements (buf); \
+    return err; \
+}
+
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT_VECTOR (Platform, cl_platform_id)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT_VECTOR (Device, cl_device_id)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT_VECTOR (Context, cl_context)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT_VECTOR (Event, cl_event)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT_VECTOR (CommandQueue, cl_command_queue)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT_VECTOR (MemoryObject, cl_mem)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT_VECTOR (Program, cl_program)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT_VECTOR (Kernel, cl_kernel)
+IMPL_GET_INFO_WITH_EXTRA_FOR_OBJECT_VECTOR (Sampler, cl_sampler)
+
+
+
+//##############################################################################
+
+
+
+NS_IMPL_THREADSAFE_ISUPPORTS0(WebCL_LibCLWrapper)
+
+
+WebCL_LibCLWrapper::WebCL_LibCLWrapper (WebCL_LibCL* aLibCL)
+  : nsISupports(),
+    mLibCL(aLibCL), mStatus(SUCCESS)
+{
+}
+
+
+WebCL_LibCLWrapper::~WebCL_LibCLWrapper ()
+{
+}
+
+
+WebCL_LibCLWrapper::Status WebCL_LibCLWrapper::status () const
+{
+  return mStatus;
+}
+
+
+WebCL_LibCL* WebCL_LibCLWrapper::library ()
+{
+  return mLibCL;
+}
+
+
+cl_int WebCL_LibCLWrapper::getPlatformIDs (nsTArray<cl_platform_id>& aPlatformsOut)
+{
+  LIBCL_WRAPPER_BEGIN (clGetPlatformIDs, 0);
+
+  cl_uint num = 0;
+  cl_int err = mLibCL->symbols->clGetPlatformIDs (0, NULL, &num);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to get number of platforms. (error %d)", err);
+    return err;
+  }
+
+  nsTArray<cl_platform_id> platforms;
+  platforms.SetLength (num);
+  err = mLibCL->symbols->clGetPlatformIDs (num, (cl_platform_id*)platforms.Elements(), NULL);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to get platforms. (error %d)", err);
+    return err;
+  }
+
+  aPlatformsOut.SwapElements (platforms);
+
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::getDeviceIDs (cl_platform_id aPlatform, int aDeviceType,
+                                         nsTArray<cl_device_id>& aDevicesOut)
+{
+  LIBCL_WRAPPER_BEGIN (clGetDeviceIDs, 0);
+
+  cl_uint num = 0;
+  cl_int err = mLibCL->symbols->clGetDeviceIDs (aPlatform, aDeviceType, 0, NULL, &num);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to get number of devices. (error %d)", err);
+    return err;
+  }
+
+  nsTArray<cl_device_id> devices;
+  devices.SetLength (num);
+  err = mLibCL->symbols->clGetDeviceIDs (aPlatform, aDeviceType, num, devices.Elements(), NULL);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to get devices. (error %d)", err);
+    return err;
+  }
+
+  aDevicesOut.SwapElements (devices);
+
+  return err;
+}
+
+
+cl_context WebCL_LibCLWrapper::createContext (cl_context_properties* aProperties,
+                                              nsTArray<cl_device_id> const& aDevices,
+                                              void (CL_CALLBACK *aNotify) (const char *, const void *, size_t cb, void *),
+                                              void* aNotifyUserData,
+                                              cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateContext, 0);
+
+  cl_int err = CL_SUCCESS;
+  cl_context ctx = mLibCL->symbols->clCreateContext (aProperties, aDevices.Length(), aDevices.Elements(),
+                                                     aNotify, aNotifyUserData, &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateContext failed with error %d.", err);
+  }
+
+  if (aErrorOut)
+    *aErrorOut = err;
+
+  return ctx;
+}
+
+
+cl_context WebCL_LibCLWrapper::createContextFromType (cl_context_properties* aProperties,
+                                                      int aDeviceType,
+                                                      void (CL_CALLBACK *aNotify) (const char *, const void *, size_t cb, void *),
+                                                      void* aNotifyUserData,
+                                                      cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateContextFromType, 0);
+
+  cl_int err = CL_SUCCESS;
+  cl_context ctx = mLibCL->symbols->clCreateContextFromType (aProperties, aDeviceType,
+                                                             aNotify, aNotifyUserData, &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateContextFromType failed with error %d.", err);
+  }
+
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+
+  return ctx;
+}
+
+
+cl_int WebCL_LibCLWrapper::retainContext (cl_context aContext)
+{
+  LIBCL_WRAPPER_BEGIN (clRetainContext, 0);
+
+  cl_int err = mLibCL->symbols->clRetainContext (aContext);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clRetainContext failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::releaseContext (cl_context aContext)
+{
+  LIBCL_WRAPPER_BEGIN (clReleaseContext, 0);
+
+  cl_int err = mLibCL->symbols->clReleaseContext (aContext);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clReleaseContext failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_command_queue WebCL_LibCLWrapper::createCommandQueue (cl_context aContext,
+                                                         cl_device_id aDevice,
+                                                         cl_command_queue_properties aProperties,
+                                                         cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateCommandQueue, 0);
+
+  cl_int err = CL_SUCCESS;
+  cl_command_queue cmdq = mLibCL->symbols->clCreateCommandQueue (aContext, aDevice, aProperties, &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateCommandQueue failed with error %d.", err);
+  }
+
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+
+  return cmdq;
+}
+
+
+cl_int WebCL_LibCLWrapper::retainCommandQueue (cl_command_queue aCmdQueue)
+{
+  LIBCL_WRAPPER_BEGIN (clRetainCommandQueue, 0);
+
+  cl_int err = mLibCL->symbols->clRetainCommandQueue (aCmdQueue);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clRetainCommandQueue failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::releaseCommandQueue (cl_command_queue aCmdQueue)
+{
+  LIBCL_WRAPPER_BEGIN (clReleaseCommandQueue, 0);
+
+  cl_int err = mLibCL->symbols->clReleaseCommandQueue (aCmdQueue);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clReleaseCommandQueue failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::setCommandQueueProperty (cl_command_queue aCmdQueue,
+                                                    cl_command_queue_properties aProperties,
+                                                    cl_bool aEnable,
+                                                    cl_command_queue_properties* aOldProperties)
+{
+  LIBCL_WRAPPER_BEGIN (clSetCommandQueueProperty, 0);
+  cl_int err = mLibCL->symbols->clSetCommandQueueProperty (aCmdQueue, aProperties, aEnable, aOldProperties);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clSetCommandQueueProperty failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_mem WebCL_LibCLWrapper::createBuffer (cl_context aContext, cl_mem_flags aFlags, size_t aSize,
+                                         void* aHostPtr, cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateBuffer, 0);
+  cl_int err = CL_SUCCESS;
+  cl_mem mem = mLibCL->symbols->clCreateBuffer (aContext, aFlags, aSize, aHostPtr, &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateBuffer failed with error %d.", err);
+  }
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+  return mem;
+}
+
+
+cl_mem WebCL_LibCLWrapper::createSubBuffer (cl_mem aBuffer, cl_mem_flags aFlags,
+                                            cl_buffer_create_type aCreateType,
+                                            const void* aCreateInfo,
+                                            cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateSubBuffer, 0);
+  cl_int err = CL_SUCCESS;
+  cl_mem mem = mLibCL->symbols->clCreateSubBuffer (aBuffer, aFlags, aCreateType,
+                                                   aCreateInfo, &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateSubBuffer failed with error %d.", err);
+  }
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+  return mem;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueReadBuffer (cl_command_queue aCmdQueue, cl_mem aBuffer,
+                                              cl_bool aBlocking,
+                                              size_t aOffset, size_t aCb, void* aPtr,
+                                              nsTArray<cl_event> const& aEventWaitList,
+                                              cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueReadBuffer, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueReadBuffer (aCmdQueue, aBuffer, aBlocking,
+                                                     aOffset, aCb, aPtr,
+                                                     ewlen,
+                                                     ewlen ? aEventWaitList.Elements () : NULL,
+                                                     aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueReadBuffer failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueWriteBuffer (cl_command_queue aCmdQueue, cl_mem aBuffer,
+                                               cl_bool aBlocking,
+                                               size_t aOffset, size_t aCb, void* aPtr,
+                                               nsTArray<cl_event> const& aEventWaitList,
+                                               cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueWriteBuffer, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueWriteBuffer (aCmdQueue, aBuffer, aBlocking,
+                                                      aOffset, aCb, aPtr,
+                                                      ewlen,
+                                                      ewlen ? aEventWaitList.Elements () : NULL,
+                                                      aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueWriteBuffer failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueReadBufferRect (cl_command_queue aCmdQueue, cl_mem aBuffer,
+                                                  cl_bool aBlocking,
+                                                  size_t const aBufferOrigin[3],
+                                                  size_t const aHostOrigin[3],
+                                                  size_t const aRegion[3],
+                                                  size_t aBufferRowPitch, size_t aBufferSlicePitch,
+                                                  size_t aHostRowPitch, size_t aHostSlicePitch,
+                                                  void* aPtr,
+                                                  nsTArray<cl_event> const& aEventWaitList,
+                                                  cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueReadBufferRect, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueReadBufferRect (aCmdQueue, aBuffer, aBlocking,
+                                                         aBufferOrigin, aHostOrigin,
+                                                         aRegion,
+                                                         aBufferRowPitch, aBufferSlicePitch,
+                                                         aHostRowPitch, aHostSlicePitch,
+                                                         aPtr,
+                                                         ewlen,
+                                                         ewlen ? aEventWaitList.Elements () : NULL,
+                                                         aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueReadBufferRect failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueWriteBufferRect (cl_command_queue aCmdQueue, cl_mem aBuffer,
+                                                   cl_bool aBlocking,
+                                                   size_t const aBufferOrigin[3],
+                                                   size_t const aHostOrigin[3],
+                                                   size_t const aRegion[3],
+                                                   size_t aBufferRowPitch, size_t aBufferSlicePitch,
+                                                   size_t aHostRowPitch, size_t aHostSlicePitch,
+                                                   void* aPtr,
+                                                   nsTArray<cl_event> const& aEventWaitList,
+                                                   cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueWriteBufferRect, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueWriteBufferRect (aCmdQueue, aBuffer, aBlocking,
+                                                          aBufferOrigin, aHostOrigin,
+                                                          aRegion,
+                                                          aBufferRowPitch, aBufferSlicePitch,
+                                                          aHostRowPitch, aHostSlicePitch,
+                                                          aPtr,
+                                                          ewlen,
+                                                          ewlen ? aEventWaitList.Elements () : NULL,
+                                                          aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueWriteBufferRect failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::retainMemObject (cl_mem aMemObject)
+{
+  LIBCL_WRAPPER_BEGIN (clRetainMemObject, 0);
+  cl_int err = mLibCL->symbols->clRetainMemObject (aMemObject);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clRetainMemObject failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::releaseMemObject (cl_mem aMemObject)
+{
+  LIBCL_WRAPPER_BEGIN (clReleaseMemObject, 0);
+  cl_int err = mLibCL->symbols->clReleaseMemObject (aMemObject);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clReleaseMemObject failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::setMemObjectDestructorCallback (cl_mem aMemObject,
+                                                           void (CL_CALLBACK* aNotify)(cl_mem, void*),
+                                                           void* aUserData)
+{
+  LIBCL_WRAPPER_BEGIN (clSetMemObjectDestructorCallback, 0);
+  cl_int err = mLibCL->symbols->clSetMemObjectDestructorCallback (aMemObject, aNotify, aUserData);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clSetMemObjectDestructorCallback failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_mem WebCL_LibCLWrapper::createImage2D (cl_context aContext, cl_mem_flags aFlags,
+                                          cl_image_format const* aImageFormat,
+                                          size_t aWidth, size_t aHeight, size_t aRowPitch,
+                                          void* aHostPtr, cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateImage2D, 0);
+  cl_int err = CL_SUCCESS;
+  cl_mem mem = mLibCL->symbols->clCreateImage2D (aContext, aFlags, aImageFormat,
+                                                 aWidth, aHeight, aRowPitch,
+                                                 aHostPtr, &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateImage2D failed with error %d.", err);
+  }
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+  return mem;
+}
+
+
+cl_mem WebCL_LibCLWrapper::createImage3D (cl_context aContext, cl_mem_flags aFlags,
+                                          cl_image_format const* aImageFormat,
+                                          size_t aWidth, size_t aHeight, size_t aDepth,
+                                          size_t aRowPitch, size_t aSlicePitch,
+                                          void* aHostPtr, cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateImage3D, 0);
+  cl_int err = CL_SUCCESS;
+  cl_mem mem = mLibCL->symbols->clCreateImage3D (aContext, aFlags, aImageFormat,
+                                                 aWidth, aHeight, aDepth,
+                                                 aRowPitch, aSlicePitch,
+                                                 aHostPtr, &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateImage3D failed with error %d.", err);
+  }
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+  return mem;
+}
+
+
+cl_int WebCL_LibCLWrapper::getSupportedImageFormats (cl_context aContext, cl_mem_flags aFlags,
+                                                     cl_mem_object_type aMemObjectType,
+                                                     nsTArray<cl_image_format>& aImageFormatsOut)
+{
+  LIBCL_WRAPPER_BEGIN (clGetSupportedImageFormats, 0);
+  cl_uint num = 0;
+  cl_int err = mLibCL->symbols->clGetSupportedImageFormats (aContext, aFlags, aMemObjectType,
+                                                            0, NULL, &num);
+  if (CL_SUCCEEDED (err))
+  {
+    nsTArray<cl_image_format> imageFormats;
+    imageFormats.SetLength (num);
+    err = mLibCL->symbols->clGetSupportedImageFormats (aContext, aFlags, aMemObjectType,
+                                                       num, imageFormats.Elements(), NULL);
+    if (CL_SUCCEEDED (err))
+    {
+      aImageFormatsOut.SwapElements (imageFormats);
+    }
+  }
+
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clGetSupportedImageFormats failed with error %d.", err);
+  }
+
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueReadImage (cl_command_queue aCmdQueue, cl_mem aImage,
+                                             cl_bool aBlocking,
+                                             size_t const aOrigin[3], size_t const aRegion[3],
+                                             size_t aRowPitch, size_t aSlicePitch, void* aPtr,
+                                             nsTArray<cl_event> const& aEventWaitList,
+                                             cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueReadImage, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueReadImage (aCmdQueue, aImage, aBlocking,
+                                                    aOrigin, aRegion, aRowPitch, aSlicePitch,
+                                                    aPtr,
+                                                    ewlen,
+                                                    ewlen ? aEventWaitList.Elements () : NULL,
+                                                    aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueReadImage failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueWriteImage (cl_command_queue aCmdQueue, cl_mem aImage,
+                                              cl_bool aBlocking,
+                                              size_t const aOrigin[3], size_t const aRegion[3],
+                                              size_t aInputRowPitch, size_t aInputSlicePitch,
+                                              void* aPtr,
+                                              nsTArray<cl_event> const& aEventWaitList,
+                                              cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueWriteImage, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueWriteImage (aCmdQueue, aImage, aBlocking,
+                                                     aOrigin, aRegion,
+                                                     aInputRowPitch, aInputSlicePitch,
+                                                     aPtr,
+                                                     ewlen,
+                                                     ewlen ? aEventWaitList.Elements () : NULL,
+                                                     aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueWriteImage failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueCopyImage (cl_command_queue aCmdQueue, cl_mem aSrcImage,
+                                             cl_mem aDstImage,
+                                             size_t const aSrcOrigin[3], size_t const aDstOrigin[3],
+                                             size_t const aRegion[3],
+                                             nsTArray<cl_event> const& aEventWaitList,
+                                             cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueCopyImage, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueCopyImage (aCmdQueue, aSrcImage, aDstImage,
+                                                    aSrcOrigin, aDstOrigin, aRegion,
+                                                    ewlen,
+                                                    ewlen ? aEventWaitList.Elements () : NULL,
+                                                    aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueCopyImage failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueCopyImageToBuffer (cl_command_queue aCmdQueue,
+                                                     cl_mem aSrcImage, cl_mem aDstBuffer,
+                                                     size_t const aSrcOrigin[3],
+                                                     size_t const aRegion[3],
+                                                     size_t aDstOffset,
+                                                     nsTArray<cl_event> const& aEventWaitList,
+                                                     cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueCopyImageToBuffer, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueCopyImageToBuffer (aCmdQueue, aSrcImage, aDstBuffer,
+                                                            aSrcOrigin, aRegion, aDstOffset,
+                                                            ewlen,
+                                                            ewlen ? aEventWaitList.Elements () : NULL,
+                                                            aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueCopyImageToBuffer failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueCopyBufferToImage (cl_command_queue aCmdQueue,
+                                                     cl_mem aSrcBuffer, cl_mem aDstImage,
+                                                     size_t aSrcOffset, size_t const aDstOrigin[3],
+                                                     size_t const aRegion[3],
+                                                     nsTArray<cl_event> const& aEventWaitList,
+                                                     cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueCopyBufferToImage, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueCopyBufferToImage (aCmdQueue, aSrcBuffer, aDstImage,
+                                                            aSrcOffset,aDstOrigin,aRegion,
+                                                            ewlen,
+                                                            ewlen ? aEventWaitList.Elements () : NULL,
+                                                            aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueCopyBufferToImage failed with error %d.", err);
+  }
+  return err;
+}
+
+
+/* TODO: Do we have counterpart for this on the IDL? */
+cl_int WebCL_LibCLWrapper::enqueueCopyBufferRect (cl_command_queue aCmdQueue,
+                                                  cl_mem aSrcBuffer, cl_mem aDstBuffer,
+                                                  size_t const aSrcOrigin[3],
+                                                  size_t const aDstOrigin[3],
+                                                  size_t const aRegion[3],
+                                                  size_t aSrcRowPitch, size_t aSrcSlicePitch,
+                                                  size_t aDstRowPitch, size_t aDstSlicePitch,
+                                                  nsTArray<cl_event> const& aEventWaitList,
+                                                  cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueCopyBufferRect, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueCopyBufferRect (aCmdQueue, aSrcBuffer, aDstBuffer,
+                                                         aSrcOrigin, aDstOrigin, aRegion,
+                                                         aSrcRowPitch, aSrcSlicePitch,
+                                                         aDstRowPitch, aDstSlicePitch,
+                                                         ewlen,
+                                                         ewlen ? aEventWaitList.Elements () : NULL,
+                                                         aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueCopyBufferRect failed with error %d.", err);
+  }
+  return err;
+}
+
+
+void* WebCL_LibCLWrapper::enqueueMapBuffer (cl_command_queue aCmdQueue, cl_mem aBuffer,
+                                            cl_bool aBlocking,
+                                            cl_map_flags aFlags, size_t aOffset, size_t aCb,
+                                            nsTArray<cl_event> const& aEventWaitList,
+                                            cl_event* aEventOut, cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueMapBuffer, 0);
+  cl_int err = CL_SUCCESS;
+  cl_uint ewlen = aEventWaitList.Length ();
+  void* res = mLibCL->symbols->clEnqueueMapBuffer (aCmdQueue, aBuffer, aBlocking,
+                                                   aFlags, aOffset, aCb,
+                                                   ewlen,
+                                                   ewlen ? aEventWaitList.Elements () : NULL,
+                                                   aEventOut, &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueMapBuffer failed with error %d.", err);
+  }
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+  return res;
+}
+
+
+void* WebCL_LibCLWrapper::enqueueMapImage (cl_command_queue aCmdQueue, cl_mem aImage,
+                                           cl_bool aBlocking, cl_map_flags aFlags,
+                                           size_t const aOrigin[3], size_t const aRegion[3],
+                                           size_t* aRowPitchOut, size_t* aSlicePitchOut,
+                                           nsTArray<cl_event> const& aEventWaitList,
+                                           cl_event* aEventOut, cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueMapImage, 0);
+  cl_int err = CL_SUCCESS;
+  cl_uint ewlen = aEventWaitList.Length ();
+  void* res = mLibCL->symbols->clEnqueueMapImage (aCmdQueue, aImage, aBlocking,
+                                                  aFlags, aOrigin, aRegion,
+                                                  aRowPitchOut, aSlicePitchOut,
+                                                  ewlen,
+                                                  ewlen ? aEventWaitList.Elements () : NULL,
+                                                  aEventOut, &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueMapImage failed with error %d.", err);
+  }
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+  return res;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueUnmapMemObject (cl_command_queue aCmdQueue, cl_mem aMemObject,
+                                                  void* aMappedPtr,
+                                                  nsTArray<cl_event> const& aEventWaitList,
+                                                  cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueUnmapMemObject, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueUnmapMemObject (aCmdQueue, aMemObject, aMappedPtr,
+                                                         ewlen,
+                                                         ewlen ? aEventWaitList.Elements () : NULL,
+                                                         aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueUnmapMemObject failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_sampler WebCL_LibCLWrapper::createSampler (cl_context aContext, cl_bool aNormalizedCoords,
+                          cl_addressing_mode aAdressingMode,
+                          cl_filter_mode aFilterMode, cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateSampler, 0);
+  cl_int err = CL_SUCCESS;
+  cl_sampler sampler = mLibCL->symbols->clCreateSampler (aContext, aNormalizedCoords,
+                                                         aAdressingMode, aFilterMode,
+                                                         &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateSampler failed with error %d.", err);
+  }
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+  return sampler;
+}
+
+
+cl_int WebCL_LibCLWrapper::retainSampler (cl_sampler aSampler)
+{
+  LIBCL_WRAPPER_BEGIN (clRetainSampler, 0);
+  cl_int err = mLibCL->symbols->clRetainSampler (aSampler);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clRetainSampler failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::releaseSampler (cl_sampler aSampler)
+{
+  LIBCL_WRAPPER_BEGIN (clReleaseSampler, 0);
+  cl_int err = mLibCL->symbols->clReleaseSampler (aSampler);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clReleaseSampler failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_program WebCL_LibCLWrapper::createProgramWithSource (cl_context aContext,
+                                                        nsCString aSource,
+                                                        cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateProgramWithSource, 0);
+  cl_int err = CL_SUCCESS;
+  char const* src = aSource.get();
+  cl_program program = mLibCL->symbols->clCreateProgramWithSource (aContext,
+                                                                   1, &src,
+                                                                   NULL, &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateProgramWithSource failed with error %d.", err);
+  }
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+  return program;
+}
+
+
+cl_program WebCL_LibCLWrapper::createProgramWithBinary (cl_context aContext,
+                                                        nsTArray<cl_device_id> const& aDevices,
+                                                        nsTArray<size_t> const& aBinaryLengths,
+                                                        nsTArray<unsigned char const*> const& aBinaries,
+                                                        nsTArray<cl_int>& aBinaryStatusOut,
+                                                        cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateProgramWithBinary, 0);
+
+  cl_int err = CL_SUCCESS;
+
+  // Ensure there's a binary for each device
+  if (aDevices.Length() != aBinaries.Length())
+  {
+    D_LOG (LOG_LEVEL_ERROR,
+           "The number of binaries (%d) does not match the number of devices (%d).",
+           aBinaries.Length(), aDevices.Length());
+  }
+
+  if (aBinaries.Length() != aBinaryLengths.Length())
+  {
+    D_LOG (LOG_LEVEL_ERROR,
+           "The number of binary lengths (%d) does not match the number of binaries (%d).",
+           aBinaryLengths.Length(), aBinaries.Length());
+  }
+
+  if (CL_FAILED (err))
+  {
+    if (aErrorOut)
+    {
+      *aErrorOut = CL_INVALID_VALUE;
+    }
+    return 0;
+  }
+
+  nsTArray<cl_int> binaryStatus;
+  binaryStatus.SetLength (aDevices.Length());
+
+  cl_program program = mLibCL->symbols->clCreateProgramWithBinary (
+                                             aContext,
+                                             aDevices.Length(),
+                                             aDevices.Elements(),
+                                             aBinaryLengths.Elements(),
+                                             (unsigned char const**)aBinaries.Elements(),
+                                             binaryStatus.Elements(),
+                                             &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateProgramWithBinary failed with error %d.", err);
+  }
+
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+
+  aBinaryStatusOut.SwapElements (binaryStatus);
+
+  return program;
+}
+
+
+cl_int WebCL_LibCLWrapper::retainProgram (cl_program aProgram)
+{
+  LIBCL_WRAPPER_BEGIN (clRetainProgram, 0);
+  cl_int err = mLibCL->symbols->clRetainProgram (aProgram);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clRetainProgram failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::releaseProgram (cl_program aProgram)
+{
+  LIBCL_WRAPPER_BEGIN (clReleaseProgram, 0);
+  cl_int err = mLibCL->symbols->clReleaseProgram (aProgram);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clReleaseProgram failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::unloadCompiler ()
+{
+  LIBCL_WRAPPER_BEGIN (clUnloadCompiler, 0);
+  cl_int err = mLibCL->symbols->clUnloadCompiler ();
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clUnloadCompiler failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::buildProgram (cl_program aProgram,
+                                         nsTArray<cl_device_id> const& aDevices,
+                                         nsCString const& aOptions,
+                                         void (CL_CALLBACK* aNotify)(cl_program, void*),
+                                         void* aUserData)
+{
+  LIBCL_WRAPPER_BEGIN (clBuildProgram, 0);
+  cl_int err = mLibCL->symbols->clBuildProgram (aProgram,
+                                                aDevices.Length(),
+                                                aDevices.Elements(),
+                                                aOptions.get(),
+                                                aNotify, aUserData);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clBuildProgram failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_kernel WebCL_LibCLWrapper::createKernel (cl_program aProgram,
+                                            nsCString aKernelName,
+                                            cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateKernel, 0);
+  cl_int err = CL_SUCCESS;
+  cl_kernel kernel = mLibCL->symbols->clCreateKernel (aProgram, aKernelName.get(),
+                                                      &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateKernel failed with error %d.", err);
+  }
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+
+  return kernel;
+}
+
+
+cl_int WebCL_LibCLWrapper::createKernelsInProgram (cl_program aProgram,
+                                                   nsTArray<cl_kernel>& aKernelsOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateKernelsInProgram, 0);
+
+  cl_uint num = 0;
+  cl_int err = mLibCL->symbols->clCreateKernelsInProgram (aProgram, 0, NULL, &num);
+  if (CL_SUCCEEDED (err))
+  {
+    nsTArray<cl_kernel> kernels;
+    kernels.SetLength (num);
+    err = mLibCL->symbols->clCreateKernelsInProgram (aProgram, kernels.Length(),
+                                                     kernels.Elements(), NULL);
+    if (CL_SUCCEEDED (err))
+    {
+      aKernelsOut.SwapElements (kernels);
+    }
+  }
+
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateKernelsInProgram failed with error %d.", err);
+  }
+
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::retainKernel (cl_kernel aKernel)
+{
+  LIBCL_WRAPPER_BEGIN (clRetainKernel, 0);
+  cl_int err = mLibCL->symbols->clRetainKernel (aKernel);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clRetainKernel failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::releaseKernel (cl_kernel aKernel)
+{
+  LIBCL_WRAPPER_BEGIN (clReleaseKernel, 0);
+  cl_int err = mLibCL->symbols->clReleaseKernel (aKernel);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clReleaseKernel failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::setKernelArg (cl_kernel aKernel, cl_uint aIndex,
+                                         size_t aSize, const void* aValue)
+{
+  LIBCL_WRAPPER_BEGIN (clSetKernelArg, 0);
+  cl_int err = mLibCL->symbols->clSetKernelArg (aKernel, aIndex, aSize, aValue);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clSetKernelArg failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueNDRangeKernel (cl_command_queue aCmdQueue, cl_kernel aKernel,
+                             cl_uint aWorkDim,
+                             nsTArray<size_t> const& aGlobalWorkOffset,
+                             nsTArray<size_t> const& aGlobalWorkSize,
+                             nsTArray<size_t> const& aLocalWorkSize,
+                             nsTArray<cl_event> const& aEventWaitList,
+                             cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueNDRangeKernel, 0);
+
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueNDRangeKernel (
+                                    aCmdQueue, aKernel,
+                                    aWorkDim,
+                                    aGlobalWorkOffset.Length()?aGlobalWorkOffset.Elements():NULL,
+                                    aGlobalWorkSize.Length()?aGlobalWorkSize.Elements():NULL,
+                                    aLocalWorkSize.Length()?aLocalWorkSize.Elements():NULL,
+                                    ewlen,
+                                    ewlen ? aEventWaitList.Elements () : NULL,
+                                    aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueNDRangeKernel failed with error %d.", err);
+  }
+
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueTask (cl_command_queue aCmdQueue, cl_kernel aKernel,
+                    nsTArray<cl_event> const& aEventWaitList,
+                    cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueTask, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueTask (aCmdQueue, aKernel,
+                                               ewlen,
+                                               ewlen ? aEventWaitList.Elements () : NULL,
+                                               aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueTask failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueNativeKernel (cl_command_queue aCmdQueue,
+                            void (CL_CALLBACK *aUserFunc)(void *),
+                            void* aArgs, size_t aCbArgs,
+                            nsTArray<cl_mem> const& aMemObjects,
+                            const void** aArgsMemLoc,
+                            nsTArray<cl_event> const& aEventWaitList,
+                            cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueNativeKernel, 0);
+  // TODO: WebCL_LibCLWrapper::enqueueNativeKernel NOT IMPLEMENTED
+  D_LOG (LOG_LEVEL_ERROR, "NOT IMPLEMENTED!");
+  return CL_INVALID_COMMAND_QUEUE;
+}
+
+
+cl_event WebCL_LibCLWrapper::createUserEvent (cl_context aContext, cl_int* aErrorOut)
+{
+  LIBCL_WRAPPER_BEGIN (clCreateUserEvent, 0);
+
+  cl_int err = CL_SUCCESS;
+  cl_event event = mLibCL->symbols->clCreateUserEvent (aContext, &err);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clCreateUserEvent failed with error %d.", err);
+  }
+  if (aErrorOut)
+  {
+    *aErrorOut = err;
+  }
+
+  return event;
+}
+
+
+cl_int WebCL_LibCLWrapper::setUserEventStatus (cl_event aEvent, cl_int aExecutionStatus)
+{
+  LIBCL_WRAPPER_BEGIN (clSetUserEventStatus, 0);
+  cl_int err = mLibCL->symbols->clSetUserEventStatus (aEvent, aExecutionStatus);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clSetUserEventStatus failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::waitForEvents (nsTArray<cl_event> const& aEvents)
+{
+  LIBCL_WRAPPER_BEGIN (clWaitForEvents, 0);
+  cl_int err = mLibCL->symbols->clWaitForEvents (aEvents.Length(), aEvents.Elements());
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clWaitForEvents failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::setEventCallback (cl_event aEvent, cl_int aCommandExecCallbackType,
+                                             void (CL_CALLBACK * aNotify)(cl_event, cl_int, void*),
+                                             void* aUserData)
+{
+  LIBCL_WRAPPER_BEGIN (clSetEventCallback, 0);
+  cl_int err = mLibCL->symbols->clSetEventCallback (aEvent, aCommandExecCallbackType,
+                                                    aNotify, aUserData);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clSetEventCallback failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::retainEvent (cl_event aEvent)
+{
+  LIBCL_WRAPPER_BEGIN (clRetainEvent, 0);
+  cl_int err = mLibCL->symbols->clRetainEvent (aEvent);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clRetainEvent failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::releaseEvent (cl_event aEvent)
+{
+  LIBCL_WRAPPER_BEGIN (clReleaseEvent, 0);
+  cl_int err = mLibCL->symbols->clReleaseEvent (aEvent);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clReleaseEvent failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueMarker (cl_command_queue aCmdQueue, cl_event* aEventOut)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueMarker, 0);
+  cl_int err = mLibCL->symbols->clEnqueueMarker (aCmdQueue, aEventOut);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueMarker failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueWaitForEvents (cl_command_queue aCmdQueue,
+                                                 nsTArray<cl_event> const& aEventWaitList)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueWaitForEvents, 0);
+  cl_uint ewlen = aEventWaitList.Length ();
+  cl_int err = mLibCL->symbols->clEnqueueWaitForEvents (aCmdQueue,
+                                                        ewlen,
+                                                        ewlen ? aEventWaitList.Elements () : NULL);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueWaitForEvents failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::enqueueBarrier (cl_command_queue aCmdQueue)
+{
+  LIBCL_WRAPPER_BEGIN (clEnqueueBarrier, 0);
+  cl_int err = mLibCL->symbols->clEnqueueBarrier (aCmdQueue);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clEnqueueBarrier failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::flush (cl_command_queue aCmdQueue)
+{
+  LIBCL_WRAPPER_BEGIN (clFlush, 0);
+  cl_int err = mLibCL->symbols->clFlush (aCmdQueue);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clFlush failed with error %d.", err);
+  }
+  return err;
+}
+
+
+cl_int WebCL_LibCLWrapper::finish (cl_command_queue aCmdQueue)
+{
+  LIBCL_WRAPPER_BEGIN (clFinish, 0);
+  cl_int err = mLibCL->symbols->clFinish (aCmdQueue);
+  if (CL_FAILED (err))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "clFinish failed with error %d.", err);
+  }
+  return err;
+}
+
diff -r 450143d2d810 browser/components/webcl/src/WebCL_clwrapper.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCL_clwrapper.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,977 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCL_CLWRAPPER_H_
+#define _WEBCL_CLWRAPPER_H_
+
+#include <cstdint>
+
+#include "WebCLCommon.h"
+#include "WebCLLogger.h"
+
+#include "nsISupports.h"
+#include "nsCOMPtr.h"
+#include "nsStringAPI.h" /*#include "nsStringGlue.h"*/
+#include "nsTArray.h"
+
+#include <CL/opencl.h>
+
+
+/** CL_SUCCEEDED evaluates to true if the OpenCL error value \c err
+ * indicates successfull operation.
+ */
+#define CL_SUCCEEDED(err) (err == CL_SUCCESS)
+
+/** CL_FAILED evaluates to true if the OpenCL error value \c err
+ * indicates failed operation.
+ */
+#define CL_FAILED(err) (err != CL_SUCCESS)
+
+
+// TODO: MOVE TO WebCLCommon.h?
+typedef void* clobject;
+
+typedef cl_int (CL_API_CALL *InfoFunc)(clobject aInstance, int aName, size_t aSize, void* aValueOut, size_t* aSizeOut);
+typedef cl_int (CL_API_CALL *InfoFuncExtra)(clobject aInstance, clobject aExtra, int aName, size_t aSize, void* aValueOut, size_t* aSizeOut);
+
+
+
+/* Explicit template specialization is not allowed within class, even though
+ * some compilers allow it. We place our getInfo-related templates and their
+ * specializations in WebCLLibWrapperDetail namespace
+ */
+namespace WebCLLibWrapperDetail {
+    // GetInfo implementations for strings
+    cl_int getInfoImpl_string (clobject aInstance, int aName, nsCString& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_string_V (clobject aInstance, int aName, nsTArray<nsCString>& aValueOut, InfoFunc infoFunc);
+
+    // GetInfo implementation for ImageFormat
+    cl_int getInfoImpl_ImageFormat (clobject aInstance, int aName, cl_image_format& aValueOut, InfoFunc infoFunc);
+
+    // GetInfo implementations functions for wrapper classes
+    cl_int getInfoImpl_Platform (clobject aInstance, int aName, cl_platform_id& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_Device (clobject aInstance, int aName, cl_device_id& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_Context (clobject aInstance, int aName, cl_context& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_Event (clobject aInstance, int aName, cl_event& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_CommandQueue (clobject aInstance, int aName, cl_command_queue& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_MemoryObject (clobject aInstance, int aName, cl_mem& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_Program (clobject aInstance, int aName, cl_program& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_Kernel (clobject aInstance, int aName, cl_kernel& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_Sampler (clobject aInstance, int aName, cl_sampler& aValueOut, InfoFunc infoFunc);
+
+    cl_int getInfoImpl_Platform_V (clobject aInstance, int aName, nsTArray<cl_platform_id>& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_Device_V (clobject aInstance, int aName, nsTArray<cl_device_id>& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_Context_V (clobject aInstance, int aName, nsTArray<cl_context>& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_Event_V (clobject aInstance, int aName, nsTArray<cl_event>& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_CommandQueue_V (clobject aInstance, int aName, nsTArray<cl_command_queue>& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_MemoryObject_V (clobject aInstance, int aName, nsTArray<cl_mem>& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_Program_V (clobject aInstance, int aName, nsTArray<cl_program>& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_Kernel_V (clobject aInstance, int aName, nsTArray<cl_kernel>& aValueOut, InfoFunc infoFunc);
+    cl_int getInfoImpl_Sampler_V (clobject aInstance, int aName, nsTArray<cl_sampler>& aValueOut, InfoFunc infoFunc);
+
+    // GetInfo implementations with extra for strings
+    cl_int getInfoImpl_string (clobject aInstance, clobject aExtra, int aName, nsCString& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_string_V (clobject aInstance, clobject aExtra, int aName, nsTArray<nsCString>& aValueOut, InfoFuncExtra infoFunc);
+
+    // GetInfo implementations functions with extra for wrapper classes
+    cl_int getInfoImpl_Platform (clobject aInstance, clobject aExtra, int aName, cl_platform_id& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_Device (clobject aInstance, clobject aExtra, int aName, cl_device_id& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_Context (clobject aInstance, clobject aExtra, int aName, cl_context& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_Event (clobject aInstance, clobject aExtra, int aName, cl_event& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_CommandQueue (clobject aInstance, clobject aExtra, int aName, cl_command_queue& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_MemoryObject (clobject aInstance, clobject aExtra, int aName, cl_mem& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_Program (clobject aInstance, clobject aExtra, int aName, cl_program& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_Kernel (clobject aInstance, clobject aExtra, int aName, cl_kernel& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_Sampler (clobject aInstance, clobject aExtra, int aName, cl_sampler& aValueOut, InfoFuncExtra infoFunc);
+
+    cl_int getInfoImpl_Platform_V (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_platform_id>& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_Device_V (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_device_id>& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_Context_V (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_context>& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_Event_V (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_event>& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_CommandQueue_V (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_command_queue>& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_MemoryObject_V (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_mem>& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_Program_V (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_program>& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_Kernel_V (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_kernel>& aValueOut, InfoFuncExtra infoFunc);
+    cl_int getInfoImpl_Sampler_V (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_sampler>& aValueOut, InfoFuncExtra infoFunc);
+
+
+    // Basic types
+    template<typename T>
+    cl_int getInfo (clobject aInstance, int aName, T& aValueOut, InfoFunc infoFunc)
+    {
+        D_METHOD_START;
+        cl_int err = CL_SUCCESS;
+        size_t sze = 0;
+        if (!infoFunc)
+        {
+            D_LOG (LOG_LEVEL_ERROR, "Invalid infoFunc argument (null).");
+            return CL_INVALID_VALUE;
+        }
+        err = infoFunc (aInstance, aName, sizeof(T), (void*)&aValueOut, &sze);
+        if (err != CL_SUCCESS)
+        {
+            D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+            return err;
+        }
+        if (sze != sizeof(T))
+        {
+            D_LOG (LOG_LEVEL_ERROR,
+                  "getInfo returned a value of unexpected size %u, expected (%u bytes)",
+                  sze, sizeof(T));
+            D_LOG (LOG_LEVEL_WARNING, "Returning synthetic error value.");
+            return CL_INVALID_VALUE;
+        }
+        return err;
+    }
+
+    // Vectors of basic types
+    template<typename T>
+    cl_int getInfo_basicV (clobject aInstance, int aName, nsTArray<T>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        size_t sze = 0;
+        cl_int err = CL_SUCCESS;
+        if (!infoFunc)
+        {
+            D_LOG (LOG_LEVEL_ERROR, "Invalid infoFunc argument (null).");
+            return CL_INVALID_VALUE;
+        }
+        err = infoFunc (aInstance, aName, 0, 0, &sze);
+        if (err != CL_SUCCESS)
+        {
+            D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+            return err;
+        }
+        nsTArray<T> v;
+        v.SetLength (sze / sizeof(T));
+        // TODO: check that memory allocation didn't fail?
+        err = infoFunc (aInstance, aName, sze, (void*)v.Elements(), 0);
+        if (err != CL_SUCCESS) {
+          D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+          return err;
+        }
+        aValueOut.SwapElements (v);
+        return err;
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<int8_t>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<uint8_t>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<int16_t>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<uint16_t>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<int32_t>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<uint32_t>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<int64_t>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<uint64_t>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<float>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<double>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aName, aValueOut, infoFunc);
+    }
+
+    // Explicit specializations for strings and string vectors
+    template <> inline
+    cl_int getInfo<nsCString> (clobject aInstance, int aName, nsCString& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_string (aInstance, aName, aValueOut, infoFunc);
+    }
+    template <> inline
+    cl_int getInfo<nsTArray<nsCString> > (clobject aInstance, int aName, nsTArray<nsCString>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_string_V (aInstance, aName, aValueOut, infoFunc);
+    }
+
+    // Explicit specializations for ImageFormats
+    template <> inline
+    cl_int getInfo<cl_image_format> (clobject aInstance, int aName, cl_image_format& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_ImageFormat (aInstance, aName, aValueOut, infoFunc);
+    }
+
+    // Explicit specializations for Wrapper-derived objects
+    template <> inline
+    cl_int getInfo (clobject aInstance, int aName, cl_platform_id& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Platform (aInstance, aName, aValueOut, infoFunc);
+    }
+    template <> inline
+    cl_int getInfo (clobject aInstance, int aName, cl_device_id& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Device (aInstance, aName, aValueOut, infoFunc);
+    }
+    template <> inline
+    cl_int getInfo (clobject aInstance, int aName, cl_context& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Context (aInstance, aName, aValueOut, infoFunc);
+    }
+    template <> inline
+    cl_int getInfo (clobject aInstance, int aName, cl_event& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Event (aInstance, aName, aValueOut, infoFunc);
+    }
+    template <> inline
+    cl_int getInfo (clobject aInstance, int aName, cl_command_queue& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_CommandQueue (aInstance, aName, aValueOut, infoFunc);
+    }
+    template <> inline
+    cl_int getInfo (clobject aInstance, int aName, cl_mem& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_MemoryObject (aInstance, aName, aValueOut, infoFunc);
+    }
+    template <> inline
+    cl_int getInfo (clobject aInstance, int aName, cl_program& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Program (aInstance, aName, aValueOut, infoFunc);
+    }
+    template <> inline
+    cl_int getInfo (clobject aInstance, int aName, cl_kernel& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Kernel (aInstance, aName, aValueOut, infoFunc);
+    }
+    template <> inline
+    cl_int getInfo (clobject aInstance, int aName, cl_sampler& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Sampler (aInstance, aName, aValueOut, infoFunc);
+    }
+
+    // Explicit specializations for vectors of Wrapper-derived objects
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<cl_platform_id>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Platform_V (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<cl_device_id>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Device_V (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<cl_context>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Context_V (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<cl_event>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Event_V (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<cl_command_queue>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_CommandQueue_V (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<cl_mem>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_MemoryObject_V (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<cl_program>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Program_V (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<cl_kernel>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Kernel_V (aInstance, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, int aName, nsTArray<cl_sampler>& aValueOut, InfoFunc infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Sampler_V (aInstance, aName, aValueOut, infoFunc);
+    }
+
+
+    // GetInfo with extra for basic types
+    template<typename T>
+    cl_int getInfo(clobject aInstance, clobject aExtra, int aName, T& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        cl_int err = CL_SUCCESS;
+        size_t sze = 0;
+        if (!infoFunc) {
+            D_LOG (LOG_LEVEL_ERROR, "Invalid infoFunc argument (null).");
+            return CL_INVALID_VALUE;
+        }
+        err = infoFunc(aInstance, aExtra, aName, sizeof(T), (void*)&aValueOut, &sze);
+        if (err != CL_SUCCESS) {
+            D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+            return err;
+        }
+        if (sze != sizeof(T)) {
+            D_LOG (LOG_LEVEL_ERROR,
+                    "getInfo returned a value of unexpected size %u, expected (%u bytes)",
+                    sze, sizeof(T));
+            D_LOG (LOG_LEVEL_WARNING, "Returning synthetic error value.");
+            return CL_INVALID_VALUE;
+        }
+        return err;
+    }
+
+    // GetInfo with extra for vectors of basic types
+    template<typename T>
+    cl_int getInfo_basicV (clobject aInstance, clobject aExtra, int aName, nsTArray<T>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        size_t sze = 0;
+        if (!infoFunc) {
+            D_LOG (LOG_LEVEL_ERROR, "Invalid infoFunc argument (null).");
+            return CL_INVALID_VALUE;
+        }
+        cl_int err = infoFunc (aInstance, aExtra, aName, 0, 0, &sze);
+        if (err != CL_SUCCESS) {
+            D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+            return err;
+        }
+        nsTArray<T> v;
+        v.SetLength (sze / sizeof(T));
+        // TODO: check that memory allocation didn't fail?
+        err = infoFunc (aInstance, aExtra, aName, sze, (void*)v.Elements(), 0);
+        if (err != CL_SUCCESS) {
+          D_LOG (LOG_LEVEL_ERROR, "getInfo for %d failed. (error %d)", aName, err);
+          return err;
+        }
+        aValueOut.SwapElements (v);
+
+        return err;
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<int8_t>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<uint8_t>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<int16_t>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<uint16_t>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<int32_t>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<uint32_t>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<int64_t>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<uint64_t>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<float>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<double>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfo_basicV (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+
+    // GetInfo with extra for strings and string vectors
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsCString& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_string (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<nsCString>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_string_V (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+
+    // GetInfo with extra for Wrapper-derived objects
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, cl_platform_id& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Platform (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, cl_device_id& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Device (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, cl_context& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Context (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, cl_event& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Event (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, cl_command_queue& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_CommandQueue (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, cl_mem& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_MemoryObject (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, cl_program& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Program (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, cl_kernel& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Kernel (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, cl_sampler& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Sampler (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+
+    // GetInfo with extra for vectors of Wrapper-derived objects
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_platform_id>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Platform_V (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_device_id>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Device_V (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_context>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Context_V (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_event>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Event_V (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_command_queue>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_CommandQueue_V (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_mem>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_MemoryObject_V (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_program>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Program_V (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_kernel>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Kernel_V (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+    template<> inline
+    cl_int getInfo (clobject aInstance, clobject aExtra, int aName, nsTArray<cl_sampler>& aValueOut, InfoFuncExtra infoFunc) {
+        D_METHOD_START;
+        return getInfoImpl_Sampler_V (aInstance, aExtra, aName, aValueOut, infoFunc);
+    }
+
+}
+
+
+// TODO! clGetSupportedImageFormats
+
+
+#define LIBCL_ENSURE_LIB_LOADED(rv) do { \
+  if (!mLibCL) { \
+    D_LOG (LOG_LEVEL_ERROR, "OpenCL Library not loaded!"); \
+    mStatus = NO_LIBRARY; \
+    return rv; \
+  } } while(0)
+
+#define LIBCL_ENSURE_SYMBOL_LOADED(sym,rv) do { \
+  if (!mLibCL->symbols->sym) { \
+    D_LOG (LOG_LEVEL_ERROR, "Symbol %s not loaded in library %s.", #sym, mLibCL->libName()); \
+    mStatus = NO_SYMBOL; \
+    return rv; \
+  } } while(0)
+
+#define LIBCL_WRAPPER_BEGIN(sym,rv) do { \
+  D_METHOD_START; \
+  mStatus = SUCCESS; \
+  LIBCL_ENSURE_LIB_LOADED (rv); \
+  LIBCL_ENSURE_SYMBOL_LOADED (sym, rv); \
+  } while (0)
+
+
+
+
+#include "WebCL_libcl.h"
+#include "WebCL_clsymbols.h"
+
+class WebCL_LibCLWrapper : public nsISupports
+{
+public:
+  enum Status {
+    SUCCESS = 0,
+    NO_LIBRARY,
+    NO_SYMBOL,
+    UNKNOWN
+  };
+
+  NS_DECL_ISUPPORTS
+
+  explicit WebCL_LibCLWrapper (WebCL_LibCL* aLibCL);
+  virtual ~WebCL_LibCLWrapper ();
+
+  Status status () const;
+  WebCL_LibCL* library ();
+
+  // OpenCL 1.1 API
+
+  // Query info parameters
+  template <typename T>
+  cl_int getPlatformInfo (cl_platform_id aInstance, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetPlatformInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aParamName, aValueOut,
+                                           (InfoFunc)mLibCL->symbols->clGetPlatformInfo);
+                                           //libcl_infoFunc_Platform);
+  }
+
+  template <typename T>
+  cl_int getDeviceInfo (cl_device_id aInstance, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetDeviceInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aParamName, aValueOut,
+                                           (InfoFunc)mLibCL->symbols->clGetDeviceInfo);
+                                           //libcl_infoFunc_Device);
+  }
+
+  template <typename T>
+  cl_int getContextInfo (cl_context aInstance, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetContextInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aParamName, aValueOut,
+                                           (InfoFunc)mLibCL->symbols->clGetContextInfo);
+                                           //libcl_infoFunc_Context);
+  }
+
+  template <typename T>
+  cl_int getCommandQueueInfo (cl_command_queue aInstance, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetCommandQueueInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aParamName, aValueOut,
+                                           (InfoFunc)mLibCL->symbols->clGetCommandQueueInfo);
+                                           //libcl_infoFunc_CommandQueue);
+  }
+
+  template <typename T>
+  cl_int getMemObjectInfo (cl_mem aInstance, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetMemObjectInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aParamName, aValueOut,
+                                           (InfoFunc)mLibCL->symbols->clGetMemObjectInfo);
+                                           //libcl_infoFunc_MemObject);
+  }
+
+  template <typename T>
+  cl_int getImageInfo (cl_mem aInstance, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetImageInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aParamName, aValueOut,
+                                           (InfoFunc)mLibCL->symbols->clGetImageInfo);
+                                           //libcl_infoFunc_Image);
+  }
+
+  template <typename T>
+  cl_int getSamplerInfo (cl_sampler aInstance, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetSamplerInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aParamName, aValueOut,
+                                           (InfoFunc)mLibCL->symbols->clGetSamplerInfo);
+                                           //libcl_infoFunc_Sampler);
+  }
+
+  template <typename T>
+  cl_int getProgramInfo (cl_program aInstance, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetProgramInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aParamName, aValueOut,
+                                           (InfoFunc)mLibCL->symbols->clGetProgramInfo);
+                                           //libcl_infoFunc_Program);
+  }
+
+  template <typename T>
+  cl_int getProgramBuildInfo (cl_program aInstance, cl_device_id aDevice, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetProgramBuildInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aDevice, aParamName, aValueOut,
+                                           (InfoFuncExtra)mLibCL->symbols->clGetProgramBuildInfo);
+                                           //libcl_infoFunc_ProgramBuild_E);
+  }
+
+  template <typename T>
+  cl_int getKernelInfo (cl_kernel aInstance, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetKernelInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aParamName, aValueOut,
+                                           (InfoFunc)mLibCL->symbols->clGetKernelInfo);
+                                           //libcl_infoFunc_Kernel);
+  }
+
+  template <typename T>
+  cl_int getKernelWorkGroupInfo (cl_kernel aInstance, cl_device_id aDevice, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetKernelWorkGroupInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aDevice, aParamName, aValueOut,
+                                           (InfoFuncExtra)mLibCL->symbols->clGetKernelWorkGroupInfo);
+                                           //libcl_infoFunc_KernelWorkGroup_E);
+  }
+
+  template <typename T>
+  cl_int getEventInfo (cl_event aInstance, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetEventInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aParamName, aValueOut,
+                                           (InfoFunc)mLibCL->symbols->clGetEventInfo);
+                                           //libcl_infoFunc_Event);
+  }
+
+  template <typename T>
+  cl_int getEventProfilingInfo (cl_event aInstance, int aParamName, T& aValueOut) {
+    LIBCL_WRAPPER_BEGIN (clGetEventProfilingInfo, 0);
+    return WebCLLibWrapperDetail::getInfo (aInstance, aParamName, aValueOut,
+                                           (InfoFunc)mLibCL->symbols->clGetEventProfilingInfo);
+                                           //libcl_infoFunc_EventProfiling);
+  }
+
+
+  // Query platform info
+
+  cl_int getPlatformIDs (nsTArray<cl_platform_id>& aPlatformsOut);
+
+  // Query devices
+
+  cl_int getDeviceIDs (cl_platform_id aPlatform, int aDeviceType,
+                       nsTArray<cl_device_id>& aDevicesOut);
+
+  // Contexts
+
+  cl_context createContext (cl_context_properties* aProperties,
+                            nsTArray<cl_device_id> const& aDevices,
+                            void (CL_CALLBACK *aNotify) (const char *, const void *, size_t cb, void *),
+                            void* aNotifyUserData,
+                            cl_int* aErrorOut);
+
+  cl_context createContextFromType (cl_context_properties* aProperties, int aDeviceType,
+                                    void (CL_CALLBACK *aNotify) (const char *, const void *, size_t cb, void *),
+                                    void* aNotifyUserData,
+                                    cl_int* aErrorOut);
+
+  cl_int retainContext (cl_context aContext);
+
+  cl_int releaseContext (cl_context aContext);
+
+  // Command queues
+
+  cl_command_queue createCommandQueue (cl_context aContext, cl_device_id aDevice,
+                                       cl_command_queue_properties aProperties,
+                                       cl_int* aErrorOut);
+
+  cl_int retainCommandQueue (cl_command_queue aCmdQueue);
+
+  cl_int releaseCommandQueue (cl_command_queue aCmdQueue);
+
+  cl_int setCommandQueueProperty (cl_command_queue aCmdQueue,
+                                  cl_command_queue_properties aProperties,
+                                  cl_bool aEnable,
+                                  cl_command_queue_properties* aOldProperties);
+
+  // Memory objects
+
+  cl_mem createBuffer (cl_context aContext, cl_mem_flags aFlags, size_t aSize,
+                       void* aHostPtr, cl_int* aErrorOut);
+
+  cl_mem createSubBuffer (cl_mem aBuffer, cl_mem_flags aFlags,
+                          cl_buffer_create_type aCreateType, const void* aCreateInfo,
+                          cl_int* aErrorOut);
+
+  cl_int enqueueReadBuffer (cl_command_queue aCmdQueue, cl_mem aBuffer, cl_bool aBlocking,
+                            size_t aOffset, size_t aCb, void* aPtr,
+                            nsTArray<cl_event> const& aEventWaitList, cl_event* aEventOut);
+
+  cl_int enqueueWriteBuffer (cl_command_queue aCmdQueue, cl_mem aBuffer, cl_bool aBlocking,
+                             size_t aOffset, size_t aCb, void* aPtr,
+                             nsTArray<cl_event> const& aEventWaitList, cl_event* aEventOut);
+
+  cl_int enqueueReadBufferRect (cl_command_queue aCmdQueue, cl_mem aBuffer, cl_bool aBlocking,
+                                size_t const aBufferOrigin[3], size_t const aHostOrigin[3],
+                                size_t const aRegion[3],
+                                size_t aBufferRowPitch, size_t aBufferSlicePitch,
+                                size_t aHostRowPitch, size_t aHostSlicePitch, void* aPtr,
+                                nsTArray<cl_event> const& aEventWaitList, cl_event* aEventOut);
+
+  cl_int enqueueWriteBufferRect (cl_command_queue aCmdQueue, cl_mem aBuffer, cl_bool aBlocking,
+                                 size_t const aBufferOrigin[3], size_t const aHostOrigin[3],
+                                 size_t const aRegion[3],
+                                 size_t aBufferRowPitch, size_t aBufferSlicePitch,
+                                 size_t aHostRowPitch, size_t aHostSlicePitch, void* aPtr,
+                                 nsTArray<cl_event> const& aEventWaitList, cl_event* aEventOut);
+
+  cl_int retainMemObject (cl_mem aMemObject);
+
+  cl_int releaseMemObject (cl_mem aMemObject);
+
+  cl_int setMemObjectDestructorCallback (cl_mem aMemObject,
+                                         void (CL_CALLBACK* aNotify)(cl_mem, void*),
+                                         void* aUserData);
+
+  cl_mem createImage2D (cl_context aContext, cl_mem_flags aFlags,
+                        cl_image_format const* aImageFormat,
+                        size_t aWidth, size_t aHeight, size_t aRowPitch,
+                        void* aHostPtr, cl_int* aErrorOut);
+
+  cl_mem createImage3D (cl_context aContext, cl_mem_flags aFlags,
+                        cl_image_format const* aImageFormat,
+                        size_t aWidth, size_t aHeight, size_t aDepth,
+                        size_t aRowPitch, size_t aSlicePitch,
+                        void* aHostPtr, cl_int* aErrorOut);
+
+  cl_int getSupportedImageFormats (cl_context aContext, cl_mem_flags aFlags,
+                                   cl_mem_object_type aMemObjectType,
+                                   nsTArray<cl_image_format>& aImageFormatsOut);
+
+  cl_int enqueueReadImage (cl_command_queue aCmdQueue, cl_mem aImage, cl_bool aBlocking,
+                           size_t const aOrigin[3], size_t const aRegion[3],
+                           size_t aRowPitch, size_t aSlicePitch, void* aPtr,
+                           nsTArray<cl_event> const& aEventWaitList, cl_event* aEventOut);
+
+  cl_int enqueueWriteImage (cl_command_queue aCmdQueue, cl_mem aImage, cl_bool aBlocking,
+                            size_t const aOrigin[3], size_t const aRegion[3],
+                            size_t aInputRowPitch, size_t aInputSlicePitch, void* aPtr,
+                            nsTArray<cl_event> const& aEventWaitList, cl_event* aEventOut);
+
+  cl_int enqueueCopyImage (cl_command_queue aCmdQueue, cl_mem aSrcImage, cl_mem aDstImage,
+                           size_t const aSrcOrigin[3], size_t const aDstOrigin[3],
+                           size_t const aRegion[3],
+                           nsTArray<cl_event> const& aEventWaitList, cl_event* aEventOut);
+
+  cl_int enqueueCopyImageToBuffer (cl_command_queue aCmdQueue,
+                                   cl_mem aSrcImage, cl_mem aDstBuffer,
+                                   size_t const aSrcOrigin[3], size_t const aRegion[3],
+                                   size_t aDstOffset,
+                                   nsTArray<cl_event> const& aEventWaitList,
+                                   cl_event* aEventOut);
+
+  cl_int enqueueCopyBufferToImage (cl_command_queue aCmdQueue,
+                                   cl_mem aSrcBuffer, cl_mem aDstImage,
+                                   size_t aSrcOffset, size_t const aDstOrigin[3],
+                                   size_t const aRegion[3],
+                                   nsTArray<cl_event> const& aEventWaitList,
+                                   cl_event* aEventOut);
+
+  cl_int enqueueCopyBufferRect (cl_command_queue aCmdQueue,
+                                cl_mem aSrcBuffer, cl_mem aDstBuffer,
+                                size_t const aSrcOrigin[3], size_t const aDstOrigin[3],
+                                size_t const aRegion[3],
+                                size_t aSrcRowPitch, size_t aSrcSlicePitch,
+                                size_t aDstRowPitch, size_t aDstSlicePitch,
+                                nsTArray<cl_event> const& aEventWaitList,
+                                cl_event* aEventOut);
+
+  void* enqueueMapBuffer (cl_command_queue aCmdQueue, cl_mem aBuffer, cl_bool aBlocking,
+                          cl_map_flags aFlags, size_t aOffset, size_t aCb,
+                          nsTArray<cl_event> const& aEventWaitList,
+                          cl_event* aEventOut, cl_int* aErrorOut);
+
+  void* enqueueMapImage (cl_command_queue aCmdQueue, cl_mem aImage,
+                         cl_bool aBlocking, cl_map_flags aFlags,
+                         size_t const aOrigin[3], size_t const aRegion[3],
+                         size_t* aRowPitchOut, size_t* aSlicePitchOut,
+                         nsTArray<cl_event> const& aEventWaitList,
+                         cl_event* aEventOut, cl_int* aErrorOut);
+
+  cl_int enqueueUnmapMemObject (cl_command_queue aCmdQueue, cl_mem aMemObject,
+                                void* aMappedPtr,
+                                nsTArray<cl_event> const& aEventWaitList,
+                                cl_event* aEventOut);
+
+  // Sampler objects
+
+  cl_sampler createSampler (cl_context aContext, cl_bool aNormalizedCoords,
+                            cl_addressing_mode aAdressingMode,
+                            cl_filter_mode aFilterMode, cl_int* aErrorOut);
+
+  cl_int retainSampler (cl_sampler aSampler);
+
+  cl_int releaseSampler (cl_sampler aSampler);
+
+  // Program objects
+
+  cl_program createProgramWithSource (cl_context aContext, nsCString aSource,
+                                      cl_int* aErrorOut);
+
+  cl_program createProgramWithBinary (cl_context aContext,
+                                      nsTArray<cl_device_id> const& aDevices,
+                                      nsTArray<size_t> const& aBinaryLengths,
+                                      nsTArray<unsigned char const*> const& aBinaries,
+                                      nsTArray<cl_int>& aBinaryStatusOut,
+                                      cl_int* aErrorOut);
+
+  cl_int retainProgram (cl_program aProgram);
+
+  cl_int releaseProgram (cl_program aProgram);
+
+  cl_int unloadCompiler ();
+
+  cl_int buildProgram (cl_program aProgram,
+                       nsTArray<cl_device_id> const& aDevices,
+                       nsCString const& aOptions,
+                       void (CL_CALLBACK* aNotify)(cl_program, void*),
+                       void* aUserData);
+
+  // Kernel objects
+
+  cl_kernel createKernel (cl_program aProgram, nsCString aKernelName,
+                          cl_int* aErrorOut);
+
+  cl_int createKernelsInProgram (cl_program aProgram,
+                                 nsTArray<cl_kernel>& aKernelsOut);
+
+  cl_int retainKernel (cl_kernel aKernel);
+
+  cl_int releaseKernel (cl_kernel aKernel);
+
+  cl_int setKernelArg (cl_kernel aKernel, cl_uint aIndex, size_t aSize,
+                       const void* aValue);
+
+  // Executing kernels
+
+  cl_int enqueueNDRangeKernel (cl_command_queue aCmdQueue, cl_kernel aKernel,
+                               cl_uint aWorkDim,
+                               nsTArray<size_t> const& aGlobalWorkOffset,
+                               nsTArray<size_t> const& aGlobalWorkSize,
+                               nsTArray<size_t> const& aLocalWorkSize,
+                               nsTArray<cl_event> const& aEventWaitList,
+                               cl_event* aEventOut);
+
+  cl_int enqueueTask (cl_command_queue aCmdQueue, cl_kernel aKernel,
+                      nsTArray<cl_event> const& aEventWaitList,
+                      cl_event* aEventOut);
+
+  cl_int enqueueNativeKernel (cl_command_queue aCmdQueue,
+                              void (CL_CALLBACK *aUserFunc)(void *),
+                              void* aArgs, size_t aCbArgs,
+                              nsTArray<cl_mem> const& aMemObjects,
+                              const void** aArgsMemLoc,
+                              nsTArray<cl_event> const& aEventWaitList,
+                              cl_event* aEventOut);
+
+  // Event objects
+
+  cl_event createUserEvent (cl_context aContext, cl_int* aErrorOut);
+
+  cl_int setUserEventStatus (cl_event aEvent, cl_int aExecutionStatus);
+
+  cl_int waitForEvents (nsTArray<cl_event> const& aEvents);
+
+  cl_int setEventCallback (cl_event aEvent, cl_int aCommandExecCallbackType,
+                           void (CL_CALLBACK * aNotify)(cl_event, cl_int, void*),
+                           void* aUserData);
+
+  cl_int retainEvent (cl_event aEvent);
+
+  cl_int releaseEvent (cl_event aEvent);
+
+  // Execution of kernels and memory objects commands
+
+  cl_int enqueueMarker (cl_command_queue aCmdQueue, cl_event* aEventOut);
+
+  cl_int enqueueWaitForEvents (cl_command_queue aCmdQueue,
+                               nsTArray<cl_event> const& aEventWaitList);
+
+  cl_int enqueueBarrier (cl_command_queue aCmdQueue);
+
+  // Profiling operations on memory objects and kernels
+
+  // Flush and finish
+
+  cl_int flush (cl_command_queue aCmdQueue);
+
+  cl_int finish (cl_command_queue aCmdQueue);
+
+
+protected:
+  nsCOMPtr<WebCL_LibCL> mLibCL;
+  Status mStatus;
+
+private:
+  WebCL_LibCLWrapper (WebCL_LibCLWrapper const&);
+  WebCL_LibCLWrapper& operator= (WebCL_LibCLWrapper const&);
+};
+
+#endif //_WEBCL_CLWRAPPER_H_
diff -r 450143d2d810 browser/components/webcl/src/WebCL_internal.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCL_internal.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,908 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCL_internal.h"
+#include "WebCLCommon.h"
+
+#include "WebCLPlatform.h"
+#include "WebCLDevice.h"
+#include "WebCLContext.h"
+#include "WebCLCommandQueue.h"
+#include "WebCLMemoryObject.h"
+#include "WebCLProgram.h"
+#include "WebCLKernel.h"
+#include "WebCLEvent.h"
+#include "WebCLSampler.h"
+
+#include <cstdlib>
+#include <cstdio>
+#include <cstdint>
+#include <cstdarg>
+#include <sstream>
+
+#include "nsXPCOM.h"
+#include "nsCOMPtr.h"
+#include "nsStringAPI.h"
+#include "nsCRT.h"
+#include "nsComponentManagerUtils.h"  // do_CreateInstance
+#include "nsIVariant.h"
+
+#include "jsproxy.h"
+#include "jswrapper.h"
+#include "jsfriendapi.h"
+
+
+nsresult WebCL_createTypesObject (JSContext *cx, nsIVariant** aResultOut)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aResultOut);
+  nsresult rv;
+
+  nsCOMPtr<nsIVariant> res;
+
+  static struct { char const* name; int value; } types[] = {
+    { "BYTE", types::BYTE },
+    { "CHAR", types::CHAR },
+    { "UCHAR", types::UCHAR },
+    { "SHORT", types::SHORT },
+    { "USHORT", types::USHORT },
+    { "INT", types::INT },
+    { "UINT", types::UINT },
+    { "LONG", types::LONG },
+    { "ULONG", types::ULONG },
+    { "BOOL", types::BOOL },
+    { "SIZE_T", types::SIZE_T },
+    { "HALF", types::HALF },
+    { "FLOAT", types::FLOAT },
+    { "DOUBLE", types::DOUBLE },
+    { "STRING", types::STRING },
+    { "PLATFORM", types::PLATFORM },
+    { "DEVICE", types::DEVICE },
+    { "CONTEXT", types::CONTEXT },
+    { "COMMAND_QUEUE", types::COMMAND_QUEUE },
+    { "MEMORY_OBJECT", types::MEMORY_OBJECT },
+    { "PROGRAM", types::PROGRAM },
+    { "KERNEL", types::KERNEL },
+    { "EVENT", types::EVENT },
+    { "SAMPLER", types::SAMPLER },
+    { "IMAGE_FORMAT", types::IMAGE_FORMAT },
+    { "ADRESSING_MODE", types::ADRESSING_MODE },
+    { "BUILD_STATUS", types::BUILD_STATUS },
+    { "CHANNEL_ORDER", types::CHANNEL_ORDER },
+    { "CHANNEL_TYPE", types::CHANNEL_TYPE },
+    { "COMMAND_QUEUE_PROPERTIES", types::COMMAND_QUEUE_PROPERTIES },
+    { "COMMAND_TYPE", types::COMMAND_TYPE },
+    { "CONTEXT_PROPERTIES", types::CONTEXT_PROPERTIES },
+    { "DEVICE_EXEC_CAPABILITIES", types::DEVICE_EXEC_CAPABILITIES },
+    { "DEVICE_FP_CONFIG", types::DEVICE_FP_CONFIG },
+    { "DEVICE_LOCAL_MEM_TYPE", types::DEVICE_LOCAL_MEM_TYPE },
+    { "DEVICE_MEM_CACHE_TYPE", types::DEVICE_MEM_CACHE_TYPE },
+    { "DEVICE_TYPE", types::DEVICE_TYPE },
+    { "FILTER_MODE", types::FILTER_MODE },
+    { "GL_OBJECT_TYPE", types::GL_OBJECT_TYPE },
+    { "MAP_FLAGS", types::MAP_FLAGS },
+    { "MEM_FENCE_FLAGS", types::MEM_FENCE_FLAGS },
+    { "MEM_FLAGS", types::MEM_FLAGS },
+    { "MEM_OBJECT_TYPE", types::MEM_OBJECT_TYPE },
+    { "BYTE_V", types::BYTE_V },
+    { "CHAR_V", types::CHAR_V },
+    { "UCHAR_V", types::UCHAR_V },
+    { "SHORT_V", types::SHORT_V },
+    { "USHORT_V", types::USHORT_V },
+    { "INT_V", types::INT_V },
+    { "UINT_V", types::UINT_V },
+    { "LONG_V", types::LONG_V },
+    { "ULONG_V", types::ULONG_V },
+    { "BOOL_V", types::BOOL_V },
+    { "SIZE_T_V", types::SIZE_T_V },
+    { "HALF_V", types::HALF_V },
+    { "FLOAT_V", types::FLOAT_V },
+    { "DOUBLE_V", types::DOUBLE_V },
+    { "STRING_V", types::STRING_V },
+    { "PLATFORM_V", types::PLATFORM_V },
+    { "DEVICE_V", types::DEVICE_V },
+    { "CONTEXT_V", types::CONTEXT_V },
+    { "COMMAND_QUEUE_V", types::COMMAND_QUEUE_V },
+    { "MEMORY_OBJECT_V", types::MEMORY_OBJECT_V },
+    { "PROGRAM_V", types::PROGRAM_V },
+    { "KERNEL_V", types::KERNEL_V },
+    { "EVENT_V", types::EVENT_V },
+    { "SAMPLER_V", types::SAMPLER_V }
+  };
+
+  if (!cx)
+  {
+    nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv);
+    NS_ENSURE_SUCCESS (rv, rv);
+    cx = stack->GetSafeJSContext ();
+    NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE);
+  }
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  JS_BeginRequest (cx);
+  JSBool ignored = JS_EnterLocalRootScope (cx);
+  (void)ignored; // ignored is there to avoid gcc warnings..
+
+  JSObject* jsObj = JS_NewObject (cx, NULL, NULL, NULL);
+
+  if (jsObj)
+  {
+    for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i)
+    {
+      js::Value val;
+      val.setInt32 (types[i].value);
+      if (!JS_SetProperty(cx, jsObj, types[i].name, &val))
+      {
+        D_LOG (LOG_LEVEL_ERROR, "Failed to set types object property \"%s\" = %d",
+               types[i].name, types[i].value);
+        break;
+      }
+    }
+
+    js::Value objVal;
+    objVal.setObjectOrNull (jsObj);
+    rv = xpc->JSToVariant (cx, objVal, getter_AddRefs (res));
+
+  }
+  else
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to create JSObject for types property.");
+    rv = NS_ERROR_FAILURE;
+  }
+
+  JS_LeaveLocalRootScope (cx);
+  JS_EndRequest(cx);
+
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*aResultOut = res);
+  return NS_OK;
+}
+
+
+nsresult WebCL_createVersionObject (JSContext *cx, nsIVariant** aResultOut)
+{
+  D_METHOD_START;
+
+  nsTArray<int> version;
+  version.SetCapacity (4);
+  version.AppendElement (WEBCL_VERSION_MAJOR);
+  version.AppendElement (WEBCL_VERSION_MINOR);
+  version.AppendElement (WEBCL_VERSION_RELEASE);
+  version.AppendElement (WEBCL_VERSION_REV);
+
+  return WebCL_convertVectorToJSArrayInVariant<int> (cx, version, types::INT_V, aResultOut, 0);
+}
+
+
+
+#define INITIAL_MSG_BUF_SIZE 128;
+nsresult WebCL_reportJSError (JSContext* cx, char const* aMsg, ...)
+{
+  D_METHOD_START;
+  nsresult rv = NS_OK;
+
+  size_t sze = INITIAL_MSG_BUF_SIZE;
+  char* msgBuf = NULL;
+  va_list ap;
+  while (true)
+  {
+    char* tmp = msgBuf;
+    msgBuf = (char*)realloc (msgBuf, sze);
+    if (!msgBuf)
+    {
+      if (tmp)
+        free (tmp);
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+    tmp = 0;
+
+    va_start (ap, aMsg);
+    int n = vsnprintf(msgBuf, sze, aMsg, ap);
+    va_end (ap);
+
+    if (n >= 0 && n < (int)sze)
+    {
+      // Successfull operation
+      break;
+    }
+    else if (n > (int)sze)
+    {
+      // n more bytes needed for buffer
+      sze = n + 1;
+    }
+    else if (n == -1)
+    {
+      // glibc 2.1 return -1 on truncate, grow the buffer and retry
+      sze *= 2;
+    }
+    else
+    {
+      // Unexpected error occurred.
+      D_LOG (LOG_LEVEL_WARNING, "Failed to format the message.");
+      free (msgBuf);
+      return NS_ERROR_FAILURE;
+    }
+  }
+
+  nsCOMPtr<nsIXPConnect> xpc;
+  JSBool ignored = JS_TRUE;
+  if (!cx)
+  {
+    nsCOMPtr<nsIThreadJSContextStack> stack;
+    stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv);
+    if (NS_FAILED(rv)) goto done;
+    cx = stack->GetSafeJSContext ();
+    NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE);
+  }
+  xpc = do_GetService (nsIXPConnect::GetCID (), &rv);
+  if (NS_FAILED(rv)) goto done;
+
+  JS_BeginRequest (cx);
+  ignored = JS_EnterLocalRootScope (cx);
+  (void)ignored;
+
+  D_LOG (LOG_LEVEL_ERROR, "Reporting error to JS: \"%s\"", msgBuf);
+#if 1
+  JS_ReportError(cx, msgBuf);
+#else
+  // JS_SetPendingException NOTE: caller must return with NS_OK or we'll just
+  //                              get the usual MOZ exception msg
+  {
+    JSString *str = JS_NewStringCopyZ(cx, msgBuf);
+    JS_SetPendingException (cx, STRING_TO_JSVAL(str));
+    JS_ReportPendingException (cx);
+
+    //JSErrorReport* report = JS_ErrorFromException (cx, STRING_TO_JSVAL(str));
+    jsval expVal;
+    if (JS_GetPendingException (cx, &expVal))
+    {
+      JSErrorReport* report = JS_ErrorFromException (cx, expVal);
+      fprintf(stderr, "report: %p\n", (void*)report);
+      if (report)
+        JS_ThrowReportedError (cx, "Fooooools!", report);
+    }
+  }
+  // TODO: Figure out a way to throw real JS exceptions with
+  // custom information. Currently, only generic XPCOM
+  // error-generated exception is thrown and the error
+  // message reported by this function is written on the
+  // JS error console.
+#endif
+
+  JS_LeaveLocalRootScope (cx);
+  JS_EndRequest(cx);
+
+done:
+  free (msgBuf);
+  return rv;
+}
+
+
+nsresult WebCL_parseOpenCLVersion (nsCString const& aVersionStr,
+                                   int& aVersionMajorOut,
+                                   int& aVersionMinorOut,
+                                   nsCString& aVendorSpecificInfoOut)
+{
+  D_METHOD_START;
+
+  // Sanity check: make sure the OpenCL version string is something valid.
+  // It must begin with "OpenCL "
+  PRInt32 m1 = aVersionStr.FindChar (' ');
+  if (!nsCString(aVersionStr.get(), m1).EqualsLiteral("OpenCL"))
+  {
+    D_LOG (LOG_LEVEL_WARNING, "Version string does not begin with \"OpenCL\".");
+    return NS_ERROR_FAILURE;
+  }
+
+  // Major version
+  PRInt32 m2 = aVersionStr.FindChar('.', m1 + 1);
+  nsresult rv;
+  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
+  rv = variant->SetAsACString (nsCString(aVersionStr.get() + m1, m2-m1));
+  NS_ENSURE_SUCCESS (rv, rv);
+  rv = variant->GetAsInt32 (&aVersionMajorOut);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  // Minor version
+  m1 = m2+1;
+  m2 = aVersionStr.FindChar(' ', m1);
+  rv = variant->SetAsACString (nsCString(aVersionStr.get() + m1, m2-m1));
+  NS_ENSURE_SUCCESS (rv, rv);
+  rv = variant->GetAsInt32 (&aVersionMinorOut);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  // Vendor specific information
+
+  aVendorSpecificInfoOut = nsCString (aVersionStr.get() + m2 + 1);
+
+  return NS_OK;
+}
+
+
+nsresult WebCL_getVariantsFromJSArray (JSContext *cx, nsIVariant* aVariant,
+                                       nsTArray<nsIVariant*> & aResultOut)
+{
+  D_METHOD_START;
+  nsresult rv;
+
+  NS_ENSURE_ARG_POINTER (aVariant);
+  PRUint16 variantType = 0;
+  rv = aVariant->GetDataType (&variantType);
+  switch (variantType)
+  {
+    // Accept VTYPE_ARRAY, VTYPE_EMPTY_ARRAY
+    case nsIDataType::VTYPE_ARRAY:
+    case nsIDataType::VTYPE_EMPTY_ARRAY:
+      // Array detected
+      break;
+    case nsIDataType::VTYPE_INTERFACE:
+    case nsIDataType::VTYPE_INTERFACE_IS:
+      // Might be a proxy object holding the array
+      break;
+
+    default:
+      D_LOG (LOG_LEVEL_ERROR, "Argument aVariant is not an array (type: %u).", variantType);
+      return NS_ERROR_INVALID_ARG;
+  }
+
+  if (!cx)
+  {
+    nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv);
+    NS_ENSURE_SUCCESS (rv, rv);
+    cx = stack->GetSafeJSContext ();
+    NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE);
+  }
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  js::Value jsVal;
+  rv = xpc->VariantToJS(cx, JS_GetGlobalObject(cx), aVariant, &jsVal);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  if ( !jsVal.isObject ())
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Argument aVariant is not a JSObject.");
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  JSObject* jsArrObj = jsVal.toObjectOrNull ();
+  if (jsArrObj && js::IsObjectProxy (jsArrObj))
+  {
+    jsArrObj = js::UnwrapObject (jsArrObj);
+  }
+
+  if (!jsArrObj || !JS_IsArrayObject (cx, jsArrObj))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Argument aVariant is not a JS Array Object.");
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  nsTArray <nsIVariant*> res;
+
+  JS_BeginRequest (cx);
+
+  JSBool ok = JS_TRUE;
+  uint32_t jsArrLen = 0;
+  ok = JS_GetArrayLength(cx, jsArrObj, &jsArrLen);
+  if (!ok)
+  {
+    JS_EndRequest(cx);
+    D_LOG (LOG_LEVEL_ERROR, "Failed to get array length.");
+    return NS_ERROR_FAILURE;
+  }
+
+  res.SetCapacity (jsArrLen);
+
+  for (uint32_t i = 0; i < jsArrLen; ++i)
+  {
+    jsval elem;
+    JSBool ok = JS_GetElement (cx, jsArrObj, i, &elem);
+    if (ok)
+    {
+      nsCOMPtr<nsIVariant> variant;
+      rv = xpc->JSValToVariant (cx, &elem, getter_AddRefs(variant));
+      if (NS_SUCCEEDED (rv))
+      {
+        res.AppendElement (variant);
+        NS_ADDREF (variant);
+      }
+      else
+      {
+        D_LOG (LOG_LEVEL_WARNING,
+              "Failed to convert element at position %d to nsIVariant. (rv %d)",
+              i+1, rv);
+      }
+    }
+    else
+    {
+        D_LOG (LOG_LEVEL_WARNING,
+               "Failed to get element at position %d to nsIVariant. (rv %d)",
+               i+1, rv);
+    }
+  }
+
+  JS_EndRequest(cx);
+
+  aResultOut.SwapElements (res);
+
+  return NS_OK;
+}
+
+
+void WebCL_releaseVariantVector (nsTArray<nsIVariant*> & aVariants)
+{
+  D_METHOD_START;
+  for (nsTArray<nsIVariant*>::index_type i = 0; i < aVariants.Length(); ++i)
+  {
+    if (aVariants[i])
+      NS_RELEASE (aVariants[i]);
+  }
+  aVariants.Clear ();
+}
+
+
+
+
+
+nsresult WebCL_convertVectorToJSArrayInVariant_string(JSContext *cx,
+                                                      nsTArray<nsCString> const& aVector,
+                                                      int aType, nsIVariant** aResultOut,
+                                                      WebCL_LibCLWrapper*)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aResultOut);
+  nsresult rv;
+
+  switch (aType)
+  {
+    case types::STRING_V:
+      // Accept string vector types
+      break;
+    default:
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Unsupported type %d, expected types::STRING_V", aType);
+      return NS_ERROR_FAILURE;
+    }
+  }
+
+  if (!cx)
+  {
+    nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv);
+    NS_ENSURE_SUCCESS (rv, rv);
+    cx = stack->GetSafeJSContext ();
+    NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE);
+  }
+
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  JS_BeginRequest (cx);
+  JSBool ignored = JS_EnterLocalRootScope (cx);
+  (void)ignored; // ignored is there to avoid gcc warnings..
+
+  JSObject* jsArr = JS_NewArrayObject (cx, aVector.Length (), NULL);
+  if (!jsArr)
+  {
+    JS_LeaveLocalRootScope (cx);
+    JS_EndRequest(cx);
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  size_t cnt = 0;
+  for (nsTArray<nsCString>::index_type i = 0; i < aVector.Length(); ++i)
+  {
+    jsval val = STRING_TO_JSVAL (JS_NewStringCopyZ (cx, aVector[i].get ()));
+    JS_SetElement (cx, jsArr, cnt++, &val);
+  }
+
+  JS_LeaveLocalRootScope (cx);
+  JS_EndRequest(cx);
+
+  // Wrap the JSArray in an nsIVariant
+  nsCOMPtr<nsIVariant> value;
+  js::Value jsValue;
+  jsValue.setObjectOrNull (jsArr);
+  rv = xpc->JSValToVariant(cx, &jsValue, getter_AddRefs(value));
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*aResultOut = value);
+
+  return NS_OK;
+}
+
+
+
+/* The following macro implements type-specific WebCL* object helpers for
+ * WebCL_convertVectorToJSArrayInVariant template function.
+ */
+// C: IWebCL class, T: OpenCL object type, CID: contract ID
+#define CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_IMPL(C,T,CID) \
+nsresult WebCL_convertVectorToJSArrayInVariant_##C (JSContext *cx,nsTArray<T> const& aVector, nsIVariant** aResultOut, WebCL_LibCLWrapper* aLibWrapper) \
+{ \
+  D_METHOD_START; \
+  NS_ENSURE_ARG_POINTER (aResultOut); \
+  nsresult rv; \
+  if (!cx) { \
+    nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv); \
+    NS_ENSURE_SUCCESS (rv, rv); \
+    cx = stack->GetSafeJSContext (); \
+    NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE); \
+  } \
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv); \
+  NS_ENSURE_SUCCESS (rv, rv); \
+  JS_BeginRequest (cx); \
+  JSBool ignored = JS_EnterLocalRootScope (cx); \
+  (void)ignored; /* ignored is there to avoid gcc warnings.. */ \
+  JSObject* jsArr = JS_NewArrayObject (cx, aVector.Length (), NULL); \
+  if (!jsArr) { \
+    JS_LeaveLocalRootScope (cx); \
+    JS_EndRequest(cx); \
+    return NS_ERROR_OUT_OF_MEMORY; \
+  } \
+  size_t cnt = 0; \
+  /* NOTE: aType is ignored. */ \
+  for (nsTArray<T>::index_type i = 0; i < aVector.Length(); ++i) { \
+    nsCOMPtr<C> xpcObj; \
+    rv = C::getInstance (aVector[i], getter_AddRefs(xpcObj), aLibWrapper); \
+    if (NS_FAILED (rv)) \
+      break; \
+    jsval val; \
+    const nsIID iid = NS_GET_IID (I##C); \
+    rv = xpc->WrapNativeToJSVal (cx, JS_GetGlobalObject(cx), xpcObj, 0, &iid, JS_TRUE, &val, 0); \
+    if (NS_FAILED (rv)) \
+      break; \
+    JS_SetElement (cx, jsArr, cnt++, &val); \
+  } \
+  JS_LeaveLocalRootScope (cx); \
+  JS_EndRequest(cx); \
+  if (NS_FAILED (rv)) \
+    return rv; \
+  /* Wrap the JSArray in an nsIVariant */ \
+  nsCOMPtr<nsIVariant> value; \
+  js::Value jsValue; \
+  jsValue.setObjectOrNull (jsArr); \
+  rv = xpc->JSValToVariant(cx, &jsValue, getter_AddRefs(value)); \
+  NS_ENSURE_SUCCESS (rv, rv); \
+  NS_ADDREF (*aResultOut = value); \
+  return NS_OK; \
+}
+
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_IMPL (WebCLPlatform, cl_platform_id, WEBCL_PLATFORM_CONTRACTID)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_IMPL (WebCLDevice, cl_device_id, WEBCL_DEVICE_CONTRACTID)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_IMPL (WebCLContext, cl_context, WEBCL_CONTEXT_CONTRACTID)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_IMPL (WebCLCommandQueue, cl_command_queue, WEBCL_COMMANDQUEUE_CONTRACTID)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_IMPL (WebCLMemoryObject, cl_mem, WEBCL_MEMORYOBJECT_CONTRACTID)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_IMPL (WebCLProgram, cl_program, WEBCL_PROGRAM_CONTRACTID)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_IMPL (WebCLKernel, cl_kernel, WEBCL_KERNEL_CONTRACTID)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_IMPL (WebCLEvent, cl_event, WEBCL_EVENT_CONTRACTID)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_IMPL (WebCLSampler, cl_sampler, WEBCL_SAMPLER_CONTRACTID)
+
+
+nsresult WebCL_convertVectorToJSArrayInVariant(JSContext *cx, nsTArray<cl_image_format> const& aVector,
+                                               nsIVariant** aResultOut, WebCL_LibCLWrapper*)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aResultOut);
+  nsresult rv;
+
+  if (!cx)
+  {
+    nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv);
+    NS_ENSURE_SUCCESS (rv, rv);
+    cx = stack->GetSafeJSContext ();
+    NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE);
+  }
+
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  JS_BeginRequest (cx);
+  JSBool ignored = JS_EnterLocalRootScope (cx);
+  (void)ignored; // ignored is there to avoid gcc warnings..
+
+  JSObject* jsArr = JS_NewArrayObject (cx, aVector.Length (), NULL);
+  if (!jsArr)
+  {
+    JS_LeaveLocalRootScope (cx);
+    JS_EndRequest(cx);
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  size_t cnt = 0;
+  for (nsTArray<cl_image_format>::index_type i = 0; i < aVector.Length(); ++i)
+  {
+    JSObject* jsObj = JS_NewObject (cx, NULL, NULL, NULL);
+    if (jsObj)
+    {
+      js::Value propChannelOrder;
+      propChannelOrder.setInt32 (aVector[i].image_channel_order);
+      js::Value propChannelDataType;
+      propChannelDataType.setInt32 (aVector[i].image_channel_data_type);
+      JS_SetProperty(cx, jsObj, "channelOrder", &propChannelOrder);
+      JS_SetProperty(cx, jsObj, "channelDataType", &propChannelDataType);
+      JS_SetProperty(cx, jsObj, "image_channel_order", &propChannelOrder);
+      JS_SetProperty(cx, jsObj, "image_channel_data_type", &propChannelDataType);
+
+      js::Value objVal;
+      objVal.setObjectOrNull (jsObj);
+      JS_SetElement (cx, jsArr, cnt++, &objVal);
+    }
+  }
+
+  JS_LeaveLocalRootScope (cx);
+  JS_EndRequest(cx);
+  if (NS_FAILED (rv))
+    return rv;
+
+  // Wrap the JSArray in an nsIVariant
+  nsCOMPtr<nsIVariant> value;
+  js::Value jsValue;
+  jsValue.setObjectOrNull (jsArr);
+  rv = xpc->JSValToVariant(cx, &jsValue, getter_AddRefs(value));
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*aResultOut = value);
+
+  return NS_OK;
+}
+
+
+nsresult WebCL_variantToJSObject (JSContext* aCx, nsIVariant* aVariant, JSObject** aResultOut)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aVariant);
+  NS_ENSURE_ARG_POINTER (aResultOut);
+  nsresult rv;
+  JSObject* res = 0;
+
+  PRUint16 variantType = 0;
+  rv = aVariant->GetDataType (&variantType);
+  if ( !(variantType == nsIDataType::VTYPE_INTERFACE
+         || variantType == nsIDataType::VTYPE_INTERFACE_IS))
+  {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  if (!aCx)
+  {
+    nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv);
+    NS_ENSURE_SUCCESS (rv, rv);
+    aCx = stack->GetSafeJSContext ();
+    NS_ENSURE_TRUE (aCx, NS_ERROR_FAILURE);
+  }
+
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+  js::Value jsVal;
+  rv = xpc->VariantToJS(aCx, JS_GetGlobalObject(aCx), aVariant, &jsVal);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ENSURE_TRUE (jsVal.isObject(), NS_ERROR_INVALID_ARG);
+
+  res = jsVal.toObjectOrNull ();
+  if (res && js::IsObjectProxy (res))
+  {
+    res = js::UnwrapObject (res);
+  }
+  NS_ENSURE_TRUE (res, NS_ERROR_INVALID_ARG);
+
+  *aResultOut = res;
+  return NS_OK;
+}
+
+
+nsresult WebCL_variantToImageFormat (JSContext *cx, nsIVariant* aVariant, cl_image_format& aResultOut)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aVariant);
+  nsresult rv;
+
+  PRUint16 variantType = 0;
+  rv = aVariant->GetDataType (&variantType);
+  if ( !(variantType == nsIDataType::VTYPE_INTERFACE
+         || variantType == nsIDataType::VTYPE_INTERFACE_IS))
+  {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  if (!cx)
+  {
+    nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv);
+    NS_ENSURE_SUCCESS (rv, rv);
+    cx = stack->GetSafeJSContext ();
+    NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE);
+  }
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+  js::Value jsVal;
+  rv = xpc->VariantToJS(cx, JS_GetGlobalObject(cx), aVariant, &jsVal);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ENSURE_TRUE (jsVal.isObject (), NS_ERROR_INVALID_ARG);
+
+  JSObject* jsObj = jsVal.toObjectOrNull ();;
+  if (jsObj && js::IsObjectProxy (jsObj))
+  {
+    jsObj = js::UnwrapObject (jsObj);
+  }
+  if (!jsObj)
+  {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  js::Value propChannelOrder;
+  if (!JS_LookupProperty (cx, jsObj, "channelOrder", &propChannelOrder))
+  {
+    if (!JS_LookupProperty (cx, jsObj, "image_channel_order", &propChannelOrder))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to read channel order property.");
+      return NS_ERROR_INVALID_ARG;
+    }
+  }
+
+  js::Value propChannelDataType;
+  if (!JS_LookupProperty (cx, jsObj, "channelDataType", &propChannelDataType))
+  {
+    if (!JS_LookupProperty (cx, jsObj, "image_channel_data_type", &propChannelDataType))
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to read channel data type property.");
+      return NS_ERROR_INVALID_ARG;
+    }
+  }
+
+  aResultOut.image_channel_order = propChannelOrder.toInt32 ();
+  aResultOut.image_channel_data_type = propChannelDataType.toInt32 ();
+  return NS_OK;
+}
+
+
+nsresult WebCL_imageFormatToVariant (JSContext *cx, cl_image_format const& aImageFormat, nsIVariant** aResultOut)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aResultOut);
+  nsresult rv = NS_OK;
+  nsCOMPtr<nsIVariant> res;
+
+  if (!cx)
+  {
+    nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv);
+    NS_ENSURE_SUCCESS (rv, rv);
+    cx = stack->GetSafeJSContext ();
+    NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE);
+  }
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  JS_BeginRequest (cx);
+  JSBool ignored = JS_EnterLocalRootScope (cx);
+  (void)ignored; // ignored is there to avoid gcc warnings..
+
+  JSObject* jsObj = JS_NewObject (cx, NULL, NULL, NULL);
+
+  if (jsObj)
+  {
+    js::Value propChannelOrder;
+    propChannelOrder.setInt32 (aImageFormat.image_channel_order);
+    js::Value propChannelDataType;
+    propChannelDataType.setInt32 (aImageFormat.image_channel_data_type);
+
+    if ( JS_SetProperty(cx, jsObj, "channelOrder", &propChannelOrder)
+        && JS_SetProperty(cx, jsObj, "channelDataType", &propChannelDataType)
+        && JS_SetProperty(cx, jsObj, "image_channel_order", &propChannelOrder)
+        && JS_SetProperty(cx, jsObj, "image_channel_data_type", &propChannelDataType) )
+    {
+
+      js::Value objVal;
+      objVal.setObjectOrNull (jsObj);
+      rv = xpc->JSToVariant (cx, objVal, getter_AddRefs (res));
+
+    }
+    else
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Failed to set JSObject properties for image format.");
+      rv = NS_ERROR_FAILURE;
+    }
+  }
+  else
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to create JSObject for image format.");
+    rv = NS_ERROR_FAILURE;
+  }
+
+  JS_LeaveLocalRootScope (cx);
+  JS_EndRequest(cx);
+
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*aResultOut = res);
+  return NS_OK;
+}
+
+
+static inline nsresult WebCL_variantToInternalVector3 (JSContext* cx, nsIVariant* aVariant,
+                                                       nsTArray<size_t>& aRegionOut)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (cx);
+  NS_ENSURE_ARG_POINTER (aVariant);
+  nsresult rv;
+
+  nsTArray<nsIVariant*> variants;
+  rv = WebCL_getVariantsFromJSArray (cx, aVariant, variants);
+  NS_ENSURE_SUCCESS (rv, rv);
+  if (variants.Length () != 3)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Variant array has %d items instead of exactly 3.",
+           variants.Length());
+    return NS_ERROR_FAILURE;
+  }
+
+  nsTArray<size_t> result;
+  result.SetCapacity (3);
+  for (nsTArray<nsIVariant*>::index_type i = 0; i < variants.Length(); ++i)
+  {
+    PRInt32 val;
+    rv = variants[i]->GetAsInt32 (&val);
+    if (NS_FAILED (rv)) {
+      D_LOG (LOG_LEVEL_ERROR, "Variant array index %d can not be converted to integer.",
+             i);
+      break;
+    }
+    result.AppendElement ((size_t)val);
+  }
+  WebCL_releaseVariantVector (variants);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  aRegionOut.SwapElements (result);
+  return NS_OK;
+}
+
+nsresult WebCL_variantToRegion (JSContext* cx, nsIVariant* aVariant,
+                                nsTArray<size_t>& aRegionOut)
+{
+  // Add any region-specific checks/modifications here
+  return WebCL_variantToInternalVector3 (cx, aVariant, aRegionOut);
+}
+
+nsresult WEBCL_variantToOrigin (JSContext* cx, nsIVariant* aVariant,
+                                nsTArray<size_t>& aOriginOut)
+{
+  // Add any origin-specific checks/modifications here
+  return WebCL_variantToInternalVector3 (cx, aVariant, aOriginOut);
+}
+
+nsresult WEBCL_variantToOffset (JSContext* cx, nsIVariant* aVariant,
+                                nsTArray<size_t>& aOffsetOut)
+{
+  // Add any offset-specific checks/modifications here
+  return WebCL_variantToInternalVector3 (cx, aVariant, aOffsetOut);
+}
+
diff -r 450143d2d810 browser/components/webcl/src/WebCL_internal.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCL_internal.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,1197 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCL_INTERNAL_H_
+#define _WEBCL_INTERNAL_H_
+
+#include "WebCLCommon.h"
+#include "WebCLPlatform.h"
+#include "WebCLDevice.h"
+#include "WebCLContext.h"
+#include "WebCLCommandQueue.h"
+#include "WebCLMemoryObject.h"
+#include "WebCLProgram.h"
+#include "WebCLKernel.h"
+#include "WebCLEvent.h"
+#include "WebCLSampler.h"
+
+#include <CL/opencl.h>
+
+#include "nsError.h"
+#include "jsapi.h"  // NOTE: need to include this _before_ nsIJSContextStack.h !
+#include "nsServiceManagerUtils.h"
+#include "nsIJSContextStack.h"
+#include "nsIXPConnect.h"
+#include "nsIVariant.h"
+#include "nsStringAPI.h" /*#include "nsStringGlue.h"*/
+#include "nsTArray.h"
+
+
+/** Return value for IDL functions when an error has been reported with
+ * WebCL_reportJSError. Note that NS_OK is intentional, any "real" XPCOM
+ * error code (e.g. NS_ERROR_FAILURE) will ignore the clear text error and
+ * produce the usual XPCOM exception.
+ */
+#define WEBCL_XPCOM_ERROR   NS_OK
+
+
+
+
+/**
+ * Enumeration of supported types for the info parameter getters (getInfo)
+ * and setKernelArg.
+ */
+
+namespace types {
+enum CLType {
+    UNKNOWN,
+
+    BYTE,
+    CHAR,
+    UCHAR,
+    SHORT,
+    USHORT,
+
+    // Basic types
+    INT,                        // cl_int
+    UINT,                       // cl_uint
+    LONG,                       // cl_long
+    ULONG,                      // cl_ulong
+    BOOL,                       // cl_bool = cl_uint                    //10
+    SIZE_T,                     // size_t
+    HALF,                       // cl_half
+    FLOAT,                      // cl_float
+    DOUBLE,                     // cl_double
+
+    // String types
+    STRING,                     // char*
+
+    // Class types
+    PLATFORM,                   // cl_platform_id
+    DEVICE,                     // cl_device_id
+    CONTEXT,                    // cl_context
+    COMMAND_QUEUE,              // cl_command_queue
+    MEMORY_OBJECT,              // cl_mem                               //20
+    PROGRAM,                    // cl_program
+    KERNEL,                     // cl_kernel
+    EVENT,                      // cl_event
+    SAMPLER,                    // cl_sampler
+
+    IMAGE_FORMAT,
+
+    // Special types
+    ADRESSING_MODE,             // cl_addressing_mode
+    BUILD_STATUS,               // cl_build_status
+    CHANNEL_ORDER,              // cl_channel_order
+    CHANNEL_TYPE,               // cl_channel_type
+    COMMAND_QUEUE_PROPERTIES,   // cl_command_queue_properties          //30
+    COMMAND_TYPE,               // cl_command_type
+    CONTEXT_PROPERTIES,         // cl_context_properties
+    // cl_d3d10_device_set_khr, cl_d3d10_device_source_khr removed
+    DEVICE_EXEC_CAPABILITIES,   // cl_device_exec_capabilities
+    DEVICE_FP_CONFIG,           // cl_device_fp_config
+    DEVICE_LOCAL_MEM_TYPE,      // cl_device_local_mem_type
+    DEVICE_MEM_CACHE_TYPE,      // cl_device_mem_cache_type
+    DEVICE_TYPE,                // cl_device_type
+    FILTER_MODE,                // cl_filter_mode
+    GL_OBJECT_TYPE,             // cl_gl_object_type
+    MAP_FLAGS,                  // cl_map_flags                         //40
+    MEM_FENCE_FLAGS,            // cl_mem_fence_flags
+    MEM_FLAGS,                  // cl_mem_flags
+    MEM_OBJECT_TYPE,            // cl_mem_object_type
+
+    // Vector types
+    BYTE_V,
+    CHAR_V,
+    UCHAR_V,
+    SHORT_V,
+    USHORT_V,
+    INT_V,                      // cl_int*
+    UINT_V,                     // cl_uint*                             //50
+    LONG_V,                     // cl_long*
+    ULONG_V,                    // cl_ulong*
+    BOOL_V,                     // cl_bool*
+    SIZE_T_V,                   // size_t*
+    HALF_V,
+    FLOAT_V,
+    DOUBLE_V,
+    STRING_V,                   // char**
+
+    PLATFORM_V,
+    DEVICE_V,                                                           //60
+    CONTEXT_V,
+    COMMAND_QUEUE_V,
+    MEMORY_OBJECT_V,
+    PROGRAM_V,
+    KERNEL_V,
+    EVENT_V,
+    SAMPLER_V,
+
+    LAST
+};
+}
+
+
+/** Create the \c types object made available to script context as \c WebCL.types .
+ * The resulting object will contain a property for each enumeration constant in
+ * \c types::CLType from \c clwrappertypes.h. Each property is given numeric value of
+ * respective enumeration constant.
+ * \see clwrappertypes.h
+ */
+nsresult WebCL_createTypesObject (JSContext *cx, nsIVariant** aResultOut);
+
+/** Create the version object made available to script context as WebCL.version.
+ * The version object is an array of four integer elements containing the WebCL
+ * major, minor and release version numbers, and version control revision number
+ * respectively.
+ * The C++ type of the object is nsIVariant.
+ */
+nsresult WebCL_createVersionObject (JSContext *cx, nsIVariant** aResultOut);
+
+
+/** Report an error message to the script context.
+ */
+nsresult WebCL_reportJSError (JSContext* cx, char const* aMsg, ...);
+
+
+/** Parse OpenCL platform version information.
+ */
+nsresult WebCL_parseOpenCLVersion (nsCString const& aVersionStr,
+                                   int& aVersionMajorOut,
+                                   int& aVersionMinorOut,
+                                   nsCString& aVendorSpecificInfoOut);
+
+/** Convert an array of nsIVariants to vector.
+ * \param aVariant nsIVariant containing the input array of nsIVariants.
+ * Accepted variant types are nsIDataType::VTYPE_ARRAY, nsIDataType::VTYPE_EMPTY_ARRAY,
+ * nsIDataType::VTYPE_INTERFACE and nsIDataType::VTYPE_INTERFACE_IS. Proxy objects
+ * are unwrapped automatically.
+ * \param aResultOut Resulting vector as out-parameter.
+ * Any existing content will be removed WITHOUT calling NS_RELEASE.
+ * \return Error value or NS_OK on success
+ */
+nsresult WebCL_getVariantsFromJSArray (JSContext *cx, nsIVariant* aVariant,
+                                       nsTArray<nsIVariant*> & aResultOut);
+
+
+/** Release nsIVariant objects contained in a vector.
+ * Simply calls NS_RELEASE for each non-null item in the vector and then
+ * clears the vector.
+ * \param aVariants Input vector.
+ */
+void WebCL_releaseVariantVector (nsTArray<nsIVariant*> & aVariants);
+
+
+
+// Vectors of basic types
+/** Template function that converts a vector of basic type items to a JSArray
+ * contained in nsIVariant.
+ */
+template<typename T>
+nsresult WebCL_convertVectorToJSArrayInVariant(JSContext *cx,
+                                               nsTArray<T> const& aVector,
+                                               int aType, nsIVariant** aResultOut,
+                                               WebCL_LibCLWrapper*)
+{
+  D_METHOD_START;
+  NS_ENSURE_ARG_POINTER (aResultOut);
+  nsresult rv;
+
+  if (!cx)
+  {
+    nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv);
+    NS_ENSURE_SUCCESS (rv, rv);
+    cx = stack->GetSafeJSContext ();
+    NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE);
+  }
+
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv);
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  JS_BeginRequest (cx);
+  JSBool ignored = JS_EnterLocalRootScope (cx);
+  (void)ignored; // ignored is there to avoid gcc warnings..
+
+  JSObject* jsArr = JS_NewArrayObject (cx, aVector.Length (), NULL);
+  if (!jsArr)
+  {
+    JS_LeaveLocalRootScope (cx);
+    JS_EndRequest(cx);
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  size_t cnt = 0;
+  switch (aType)
+  {
+    case types::BYTE_V:
+    case types::CHAR_V:
+    case types::UCHAR_V:
+    case types::SHORT_V:
+    case types::USHORT_V:
+    case types::INT_V:
+    case types::UINT_V:
+    case types::LONG_V:
+    case types::ULONG_V:
+    case types::SIZE_T_V:
+    case types::HALF_V: // TODO: how should we handle HALF_V?
+      // integers
+      for (typename nsTArray<T>::index_type i = 0; i < aVector.Length(); ++i)
+      {
+        js::Value val;
+        if (val.setNumber ((double)aVector[i]))
+        {
+          JS_SetElement (cx, jsArr, cnt++, &val);
+        }
+        else
+        {
+          WebCL_reportJSError (cx, "Failed to convert internal integer value to JavaScript value.");
+          rv = NS_ERROR_FAILURE;
+        }
+      }
+      break;
+    case types::BOOL_V:
+      // booleans
+      for (typename nsTArray<T>::index_type i = 0; i < aVector.Length(); ++i)
+      {
+        js::Value val;
+        val.setBoolean (aVector[i]);
+        JS_SetElement (cx, jsArr, cnt++, &val);
+      }
+      break;
+    case types::FLOAT_V:
+    case types::DOUBLE_V:
+      // floating points
+      for (typename nsTArray<T>::index_type i = 0; i < aVector.Length(); ++i)
+      {
+        js::Value val;
+        val.setDouble (aVector[i]);
+        JS_SetElement (cx, jsArr, cnt++, &val);
+      }
+      break;
+    default: {
+        D_LOG (LOG_LEVEL_ERROR, "Unsupported type %d.", aType);
+        // TODO: this error message is probably lost
+        WebCL_reportJSError (cx, "Unsupported type %d.", aType);
+        rv = NS_ERROR_FAILURE;
+      }
+      break;
+  }
+
+  JS_LeaveLocalRootScope (cx);
+  JS_EndRequest(cx);
+  if (NS_FAILED (rv))
+    return rv;
+
+  // Wrap the JSArray in an nsIVariant
+  nsCOMPtr<nsIVariant> value;
+  js::Value jsValue;
+  jsValue.setObject (*jsArr);
+  rv = xpc->JSValToVariant(cx, &jsValue, getter_AddRefs(value));
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  NS_ADDREF (*aResultOut = value);
+
+  return NS_OK;
+}
+
+
+/* The following type-specific conversion functions are called by
+ * WebCL_convertVectorToJSArrayInVariant template function specializations
+ * below them. This approach allows the actual implementations to reside
+ * in WebCLCommon.cpp while the template wrapper is exposed from this header.
+ */
+
+/** Convert a vector of nsCString to a JSArray of strings contained in nsIVariant. */
+nsresult WebCL_convertVectorToJSArrayInVariant_string(JSContext *cx,
+                                                      nsTArray<nsCString> const& aVector,
+                                                      int aType, nsIVariant** aResultOut,
+                                                      WebCL_LibCLWrapper*);
+
+/** Convert a vector of PlatformWrapper instance pointers to a JSArray of WebCLPlatforms contained in nsIVariant. */
+nsresult WebCL_convertVectorToJSArrayInVariant_WebCLPlatform(JSContext *cx,
+                                               nsTArray<cl_platform_id> const& aVector,
+                                               nsIVariant** aResultOut,
+                                               WebCL_LibCLWrapper* aLibWrapper);
+/** Convert a vector of DeviceWrapper instance pointers to a JSArray of WebCLDevices contained in nsIVariant. */
+nsresult WebCL_convertVectorToJSArrayInVariant_WebCLDevice(JSContext *cx,
+                                               nsTArray<cl_device_id> const& aVector,
+                                               nsIVariant** aResultOut,
+                                               WebCL_LibCLWrapper* aLibWrapper);
+/** Convert a vector of ContextWrapper instance pointers to a JSArray of WebCLContexts contained in nsIVariant. */
+nsresult WebCL_convertVectorToJSArrayInVariant_WebCLContext(JSContext *cx,
+                                               nsTArray<cl_context> const& aVector,
+                                               nsIVariant** aResultOut,
+                                               WebCL_LibCLWrapper* aLibWrapper);
+/** Convert a vector of CommandQueueWrapper instance pointers to a JSArray of WebCLCommandQueues contained in nsIVariant. */
+nsresult WebCL_convertVectorToJSArrayInVariant_WebCLCommandQueue(JSContext *cx,
+                                               nsTArray<cl_command_queue> const& aVector,
+                                               nsIVariant** aResultOut,
+                                               WebCL_LibCLWrapper* aLibWrapper);
+/** Convert a vector of MemoryObjectWrapper instance pointers to a JSArray of WebCLMemoryObjects contained in nsIVariant. */
+nsresult WebCL_convertVectorToJSArrayInVariant_WebCLMemoryObject(JSContext *cx,
+                                               nsTArray<cl_mem> const& aVector,
+                                               nsIVariant** aResultOut,
+                                               WebCL_LibCLWrapper* aLibWrapper);
+/** Convert a vector of ProgramWrapper instance pointers to a JSArray of WebCLPrograms contained in nsIVariant. */
+nsresult WebCL_convertVectorToJSArrayInVariant_WebCLProgram(JSContext *cx,
+                                               nsTArray<cl_program> const& aVector,
+                                               nsIVariant** aResultOut,
+                                               WebCL_LibCLWrapper* aLibWrapper);
+/** Convert a vector of KernelWrapper instance pointers to a JSArray of WebCLKernels contained in nsIVariant. */
+nsresult WebCL_convertVectorToJSArrayInVariant_WebCLKernel(JSContext *cx,
+                                               nsTArray<cl_kernel> const& aVector,
+                                               nsIVariant** aResultOut,
+                                               WebCL_LibCLWrapper* aLibWrapper);
+/** Convert a vector of EventWrapper instance pointers to a JSArray of WebCLEvents contained in nsIVariant. */
+nsresult WebCL_convertVectorToJSArrayInVariant_WebCLEvent(JSContext *cx,
+                                               nsTArray<cl_event> const& aVector,
+                                               nsIVariant** aResultOut,
+                                               WebCL_LibCLWrapper* aLibWrapper);
+/** Convert a vector of SamplerWrapper instance pointers to a JSArray of WebCLSamplers contained in nsIVariant. */
+nsresult WebCL_convertVectorToJSArrayInVariant_WebCLSampler(JSContext *cx,
+                                               nsTArray<cl_sampler> const& aVector,
+                                               nsIVariant** aResultOut,
+                                               WebCL_LibCLWrapper* aLibWrapper);
+
+
+/** WebCL_convertVectorToJSArrayInVariant template function specializations for
+ *  WebCL* object types. These implementations simply relay the call to
+ *  type-specific implementation.
+ *  NOTE: The second parameter, type, is ignored.
+ */
+#define CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_DEF(C,T) \
+  template<> inline \
+  nsresult WebCL_convertVectorToJSArrayInVariant<T>(JSContext *cx, nsTArray<T> const& aVector, \
+                                               int, nsIVariant** aResultOut, \
+                                               WebCL_LibCLWrapper* aLibWrapper) { \
+    return WebCL_convertVectorToJSArrayInVariant_##C (cx, (nsTArray<T> const)aVector, \
+                                                      aResultOut, aLibWrapper); \
+  }
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_DEF (WebCLPlatform, cl_platform_id)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_DEF (WebCLDevice, cl_device_id)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_DEF (WebCLContext, cl_context)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_DEF (WebCLCommandQueue, cl_command_queue)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_DEF (WebCLMemoryObject, cl_mem)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_DEF (WebCLProgram, cl_program)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_DEF (WebCLKernel, cl_kernel)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_DEF (WebCLEvent, cl_event)
+CONVERT_TO_JSARRAY_IN_VARIANT_TEMPL_DEF (WebCLSampler, cl_sampler)
+
+
+// String vectors
+/** WebCL_convertVectorToJSArrayInVariant template function specializations for
+ *  strings. This implementation simply relays the call to the type-specific
+ *  implementation.
+ */
+template<> inline
+nsresult WebCL_convertVectorToJSArrayInVariant<nsCString>(JSContext *cx,
+                                                          nsTArray<nsCString> const& aVector,
+                                                          int aType, nsIVariant** aResultOut,
+                                                          WebCL_LibCLWrapper*)
+{
+  D_METHOD_START;
+  return WebCL_convertVectorToJSArrayInVariant_string (cx, aVector, aType, aResultOut, 0);
+}
+
+
+// ImageFormatWrapper vectors
+/** Convert a vector of ImageFormatWrappers to a JSArray contained in an nsIVariant.
+ * NOTE: This is not a specialized template but an overloaded function!
+ */
+nsresult WebCL_convertVectorToJSArrayInVariant(JSContext *cx,
+                                               nsTArray<cl_image_format> const& aVector,
+                                               nsIVariant** aResultOut,
+                                               WebCL_LibCLWrapper*);
+
+
+/** Get JSObject from an nsIVariant.
+ * \param aCx A valid JSContext or NULL.
+ * \param aVariant An nsIVariant containing a JavaScript object.
+ * \param aResultOut Out-pointer for result.
+ * \return Error code or NS_OK on success.
+ */
+nsresult WebCL_variantToJSObject (JSContext* aCx, nsIVariant* aVariant, JSObject** aResultOut);
+
+
+/** Convert an nsIVariant containing a JSObject to ImageFormatWrapper.
+ * \param aVariant An nsIVariant containing a JSObject with \c channelOrder and
+ * \c channelDataType properties. Also \c image_channel_order and
+ * \c image_channel_data_type are accepted respectively, if primary properties
+ * are not available.
+ * \param aResultOut Out-parameter for result.
+ * \return Error code or NS_OK on success.
+ */
+nsresult WebCL_variantToImageFormat (JSContext *cx, nsIVariant* aVariant, cl_image_format& aResultOut);
+
+
+/** Convert ImageFormatWrapper to a JSObject in an nsIVariant.
+ * Resulting JSObject will have properties \c channelOrder and \c channelDataType
+ * containing values of respective ImageFormatWrapper members.
+ * \param aImageFormat ImageFormatWrapper instance.
+ * \param aResultOut Out-pointer for result.
+ */
+nsresult WebCL_imageFormatToVariant (JSContext *cx, cl_image_format const& aImageFormat, nsIVariant** aResultOut);
+
+
+/** Template function that converts a vectpr of nsIVariants containing WebCL*
+ * class instances to a vector of internal OpenCL resources.
+ * \param aVariants A vector of nsIVariants containing instances of T_WebCLInterface.
+ * \param aResultOut resulting vector as out-parameter.
+ * Any existing content will be removed.
+ * \return Error value or NS_OK on success
+ */
+template <typename T_WebCLInterface, typename T_ocl>
+nsresult WebCL_convertVariantVectorToInternalVector (nsTArray<nsIVariant*> const& aVariants,
+                                                     nsTArray<T_ocl>& aWrappersOut)
+{
+  D_METHOD_START;
+  nsresult rv;
+  nsTArray<T_ocl> result;
+  result.SetCapacity (aVariants.Length ());
+
+  rv = NS_OK;
+  for (typename nsTArray<nsIVariant*>::index_type i = 0; i < aVariants.Length(); ++i)
+  {
+    if (!aVariants[i])
+    {
+      D_LOG (LOG_LEVEL_ERROR, "Invalid non-variant element at position %d.", i+1);
+      rv = NS_ERROR_FAILURE;
+      break;
+    }
+
+    nsCOMPtr<nsISupports> isu;
+    rv = aVariants[i]->GetAsISupports (getter_AddRefs(isu));
+    if (NS_FAILED (rv))
+    {
+      D_LOG (LOG_LEVEL_ERROR,
+             "Expected nsISupports element at position %d. (rv %d)", i+1, rv);
+      break;
+    }
+    nsCOMPtr<T_WebCLInterface> impl = do_QueryInterface (isu, &rv);
+    if (NS_FAILED (rv))
+    {
+      D_LOG (LOG_LEVEL_ERROR,
+             "Failed to convert element at position %d to XPCOM implementation. (rv %d)",
+             i+1, rv);
+      break;
+    }
+
+    result.AppendElement ((T_ocl)(impl->getInternal ()));
+  }
+  NS_ENSURE_SUCCESS (rv, rv);
+
+  aWrappersOut.SwapElements (result);
+  return NS_OK;
+}
+
+
+nsresult WebCL_variantToRegion (JSContext* cx, nsIVariant* aVariant,
+                                nsTArray<size_t>& aRegionOut);
+
+nsresult WEBCL_variantToOrigin (JSContext* cx, nsIVariant* aVariant,
+                                nsTArray<size_t>& aOriginOut);
+
+nsresult WEBCL_variantToOffset (JSContext* cx, nsIVariant* aVariant,
+                                nsTArray<size_t>& aOffsetOut);
+
+
+
+//==============================================================================
+
+/**
+ * The following macros implement getInfo calls and type conversions of the
+ * resulting values to nsIVariants.
+ *
+ * the _FUN_ variants take a function pointer to the actual info function wrapper,
+ * whereas the non-_FUN_ variants take pointer to the wrapper instance itself.
+ *
+ * \param name The name (enum) of an info parameter.
+ * \param infoFunc The getInfo class function from a Wrapper class.
+ * \param internal Internal OpenCL resource.
+ * \param variant An nsIVariant instance.
+ * \param err Out-parameter for OpenCL error code.
+ * \param rv Out-parameter for Mozilla error code.
+ */
+
+// Sadly, we can't use templates or other forms of function overloading here
+// since e.g. cl_bool is typedef for cl_uint and we want to handle integers
+// and booleans separately for nsIVariants.
+
+#define GETINFO_MEDIATOR_FUN_CHAR(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_char val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsInt8 (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_UCHAR(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_uchar val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsUint8 (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_SHORT(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_short val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsInt16 (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_USHORT(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_ushort val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsUint16 (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_INT(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_int val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsInt32 (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_UINT(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_uint val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsUint32 (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_LONG(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_long val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsInt64 (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_ULONG(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_ulong val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsUint64 (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_BOOL(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_bool val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsBool (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_SIZET(name,lib,infoFunc,internal,variant,err,rv) { \
+      size_t val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsUint32 (val); /* FIXME: Proper type? */ \
+    }
+
+#define GETINFO_MEDIATOR_FUN_HALF(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_half val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsUint16 (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_FLOAT(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_float val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsFloat (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_DOUBLE(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_double val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsDouble (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_STRING(name,lib,infoFunc,internal,variant,err,rv) { \
+      nsCString val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsACString (val); \
+    }
+
+#define GETINFO_MEDIATOR_FUN_IMAGE_FORMAT(name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_image_format val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) { \
+          nsIWritableVariant* res; \
+          rv = WebCL_imageFormatToVariant (cx, val, (nsIVariant**)&res); \
+          variant = already_AddRefed<nsIWritableVariant>(res); \
+      } \
+    }
+
+/**
+ * The following macros implement getInfo calls and type conversions of the
+ * resulting values to nsIVariants for WebCL* object types.
+ * \param cltype An internal OpenCL type of the resulting value.
+ * \param Twebcl Respective WebCL* class of the resulting value.
+ * Other params are similar to previous macros.
+ */
+#define GETINFO_MEDIATOR_FUN_OBJECT(cltype,Twebcl,name,lib,infoFunc,internal,variant,err,rv) { \
+      cltype val = 0; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) { \
+        nsCOMPtr<Twebcl> xpcObj; \
+        rv = Twebcl::getInstance (val, getter_AddRefs(xpcObj), lib); \
+        if (NS_FAILED (rv)) break; \
+        rv = variant->SetAsInterface (NS_GET_IID (I##Twebcl), xpcObj); \
+      } \
+    }
+
+/**
+ * The following macros implement getInfo calls and type conversions of the
+ * resulting values to nsIVariants for vector types types.
+ * There must be a compatible specialization of WebCL_convertVectorToJSArrayInVariant
+ * for the vector type.
+ * \param Tvector The type of vector items.
+ * \param Ttypes The type of expected interpretation of the data as an enum from
+ * clwrappertypes.h .
+ * Other params are similar to previous macros.
+ *
+ * \see WebCL_convertVectorToJSArrayInVariant
+ * \see clwrappertypes.h
+ */
+#define GETINFO_MEDIATOR_FUN_VECTOR(Tvector,Ttypes,name,lib,infoFunc,internal,variant,err,rv) { \
+      nsTArray<Tvector> val; \
+      err = lib->infoFunc (internal, name, val); \
+      if (CL_SUCCEEDED (err)) \
+        rv = WebCL_convertVectorToJSArrayInVariant (cx, val, Ttypes, (nsIVariant**)&variant, lib); \
+    }
+
+
+/** The following macros build switch statement case labels from type enums in
+ * clwrappertypes.h using the macros defined above.
+ */
+
+#define GETINFO_MEDIATOR_SWITCH_HELPER_FUN_SIMPLE(name,lib,infoFunc,internal,variant,err,rv) \
+    case types::BYTE: \
+    case types::CHAR: \
+        GETINFO_MEDIATOR_FUN_CHAR (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::UCHAR: \
+        GETINFO_MEDIATOR_FUN_UCHAR (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::SHORT: \
+        GETINFO_MEDIATOR_FUN_SHORT (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::USHORT: \
+        GETINFO_MEDIATOR_FUN_USHORT (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::BUILD_STATUS: \
+    case types::INT: \
+        GETINFO_MEDIATOR_FUN_INT (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::ADRESSING_MODE: \
+    case types::CHANNEL_ORDER: \
+    case types::CHANNEL_TYPE: \
+    case types::COMMAND_TYPE: \
+    case types::DEVICE_LOCAL_MEM_TYPE: \
+    case types::DEVICE_MEM_CACHE_TYPE: \
+    case types::FILTER_MODE: \
+    case types::GL_OBJECT_TYPE: \
+    case types::MEM_OBJECT_TYPE: \
+    case types::UINT: \
+        GETINFO_MEDIATOR_FUN_UINT (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::LONG: \
+        GETINFO_MEDIATOR_FUN_LONG (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::COMMAND_QUEUE_PROPERTIES: \
+    case types::DEVICE_EXEC_CAPABILITIES: \
+    case types::DEVICE_FP_CONFIG: \
+    case types::DEVICE_TYPE: \
+    case types::MAP_FLAGS: \
+    case types::MEM_FLAGS: \
+    case types::ULONG: \
+        GETINFO_MEDIATOR_FUN_ULONG (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::BOOL: \
+        GETINFO_MEDIATOR_FUN_BOOL (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::SIZE_T: \
+        GETINFO_MEDIATOR_FUN_SIZET (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::HALF: \
+        GETINFO_MEDIATOR_FUN_HALF (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::FLOAT: \
+        GETINFO_MEDIATOR_FUN_FLOAT (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::DOUBLE: \
+        GETINFO_MEDIATOR_FUN_DOUBLE (name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::IMAGE_FORMAT: \
+        GETINFO_MEDIATOR_FUN_IMAGE_FORMAT (name, lib, infoFunc, internal, variant, err, rv); break;
+
+#define GETINFO_MEDIATOR_SWITCH_HELPER_FUN_STRINGS(name,lib,infoFunc,internal,variant,err,rv) \
+    case types::STRING: \
+        GETINFO_MEDIATOR_FUN_STRING (name, lib, infoFunc, internal, variant, err, rv); break;
+
+#define GETINFO_MEDIATOR_SWITCH_HELPER_FUN_OBJECTS(name,lib,infoFunc,internal,variant,err,rv) \
+    case types::PLATFORM: \
+      GETINFO_MEDIATOR_FUN_OBJECT (cl_platform_id, WebCLPlatform, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::DEVICE: \
+      GETINFO_MEDIATOR_FUN_OBJECT (cl_device_id, WebCLDevice, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::CONTEXT: \
+      GETINFO_MEDIATOR_FUN_OBJECT (cl_context, WebCLContext, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::COMMAND_QUEUE: \
+      GETINFO_MEDIATOR_FUN_OBJECT (cl_command_queue, WebCLCommandQueue, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::MEMORY_OBJECT: \
+      GETINFO_MEDIATOR_FUN_OBJECT (cl_mem, WebCLMemoryObject, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::PROGRAM: \
+      GETINFO_MEDIATOR_FUN_OBJECT (cl_program, WebCLProgram, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::KERNEL: \
+      GETINFO_MEDIATOR_FUN_OBJECT (cl_kernel, WebCLKernel, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::EVENT: \
+      GETINFO_MEDIATOR_FUN_OBJECT (cl_event, WebCLEvent, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::SAMPLER: \
+      GETINFO_MEDIATOR_FUN_OBJECT (cl_sampler, WebCLSampler, name, lib, infoFunc, internal, variant, err, rv); break;
+
+#define GETINFO_MEDIATOR_SWITCH_HELPER_FUN_VECTORS_SIMPLE(name,lib,infoFunc,internal,variant,err,rv) \
+    case types::BYTE_V: \
+    case types::CHAR_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_char, types::CHAR_V, name, lib, infoFunc, internal, variant, err, rv); \
+        break; \
+    case types::UCHAR_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_uchar, types::UCHAR_V, name, lib, infoFunc, internal, variant, err, rv); \
+        break; \
+    case types::SHORT_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_short, types::SHORT_V, name, lib, infoFunc, internal, variant, err, rv); \
+        break; \
+    case types::USHORT_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_ushort, types::USHORT_V, name, lib, infoFunc, internal, variant, err, rv); \
+        break; \
+    case types::CONTEXT_PROPERTIES: \
+    case types::INT_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_int, types::INT_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::UINT_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_uint, types::UINT_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::LONG_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_long, types::LONG_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::ULONG_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_ulong, types::ULONG_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::BOOL_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_bool, types::BOOL_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::SIZE_T_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (size_t, types::SIZE_T_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::HALF_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_half, types::HALF_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::FLOAT_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_float, types::FLOAT_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::DOUBLE_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_double, types::DOUBLE_V, name, lib, infoFunc, internal, variant, err, rv); break;
+
+#define GETINFO_MEDIATOR_SWITCH_HELPER_FUN_VECTORS_STRINGS(name,lib,infoFunc,internal,variant,err,rv) \
+    case types::STRING_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (nsCString, types::STRING_V, name, lib, infoFunc, internal, variant, err, rv); break;
+
+#define GETINFO_MEDIATOR_SWITCH_HELPER_FUN_VECTORS_OBJECTS(name,lib,infoFunc,internal,variant,err,rv) \
+    case types::PLATFORM_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_platform_id, types::PLATFORM_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::DEVICE_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_device_id, types::DEVICE_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::CONTEXT_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_context, types::CONTEXT_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::COMMAND_QUEUE_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_command_queue, types::COMMAND_QUEUE_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::MEMORY_OBJECT_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_mem, types::MEMORY_OBJECT_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::PROGRAM_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_program, types::PROGRAM_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::KERNEL_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_kernel, types::KERNEL_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::EVENT_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_event, types::EVENT_V, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::SAMPLER_V: \
+        GETINFO_MEDIATOR_FUN_VECTOR (cl_sampler, types::SAMPLER_V, name, lib, infoFunc, internal, variant, err, rv); break;
+
+
+#define GETINFO_MEDIATOR_SWITCH_HELPER_FUN_VECTORS(name,lib,infoFunc,internal,variant,err,rv) \
+    GETINFO_MEDIATOR_SWITCH_HELPER_FUN_VECTORS_SIMPLE (name, lib, infoFunc, internal, variant, err, rv) \
+    GETINFO_MEDIATOR_SWITCH_HELPER_FUN_VECTORS_STRINGS (name, lib, infoFunc, internal, variant, err, rv) \
+    GETINFO_MEDIATOR_SWITCH_HELPER_FUN_VECTORS_OBJECTS (name, lib, infoFunc, internal, variant, err, rv)
+
+#define GETINFO_MEDIATOR_SWITCH_HELPER_FUN_ALL(name,lib,infoFunc,internal,variant,err,rv) \
+    GETINFO_MEDIATOR_SWITCH_HELPER_FUN_SIMPLE (name, lib, infoFunc, internal, variant, err, rv) \
+    GETINFO_MEDIATOR_SWITCH_HELPER_FUN_STRINGS (name, lib, infoFunc, internal, variant, err, rv) \
+    GETINFO_MEDIATOR_SWITCH_HELPER_FUN_OBJECTS (name, lib, infoFunc, internal, variant, err, rv) \
+    GETINFO_MEDIATOR_SWITCH_HELPER_FUN_VECTORS (name, lib, infoFunc, internal, variant, err, rv)
+
+
+/** This macro implements the switch statement for getXInfo using the
+ * GETINFO_MEDIATOR_SWITCH_HELPER macros.
+ * \param aName The property name enum.
+ * \param aType The property type, e.g. types::UINT.
+ * \param aFunc The getInfo helper function, e.g. ContextWrapper::getInfo.
+ * \param aInternal Internal OpenCL resource.
+ * \param aVariant An nsIVariant instance.
+ * \param aErr A variable for the OpenCL error code.
+ * \param aNSErr A variable for the NS error code (nsresult).
+ * Note: Function return value must be nsresult.
+ */
+#define WEBCL_GETINFO_MEDIATOR_SWITCH(aName,aType,aLib,aFunc,aInternal,aVariant,aErr,aNSErr) do{ \
+    switch (aType) { \
+      GETINFO_MEDIATOR_SWITCH_HELPER_FUN_ALL (aName, aLib, aFunc, aInternal, aVariant, aErr, aNSErr)\
+      default: {\
+        D_LOG (LOG_LEVEL_ERROR, "Requested unsupported property %d.", aName); \
+        WebCL_reportJSError (cx, "%s: Requested unsupported property %d with type %d.", __FUNCTION__, aName, aType); \
+        return WEBCL_XPCOM_ERROR; /*NS_ERROR_INVALID_ARG;*/ \
+      } \
+    }\
+    if (CL_FAILED (aErr) || NS_FAILED (aNSErr)) { \
+      D_LOG (LOG_LEVEL_ERROR, "%s failed, clError: %d, mozError: %d", \
+      __FUNCTION__, aErr, aNSErr); \
+      WebCL_reportJSError (cx, "%s failed with error %d.", __FUNCTION__, aErr); \
+      return WEBCL_XPCOM_ERROR; /*NS_ERROR_FAILURE;*/ \
+    } \
+  }while(0)
+
+
+
+/** The following macros are similar to those defined above except that these
+ * variants take an extra argument for use with e.g.
+ * WebCLProgram::GetProgramBuildInfo .
+ */
+#define GETINFO_MEDIATOR_EXTRA_FUN_CHAR(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_char val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsInt8 (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_UCHAR(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_uchar val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsUint8 (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_SHORT(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_short val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsInt16 (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_USHORT(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_ushort val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsUint16 (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_INT(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_int val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsInt32 (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_UINT(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_uint val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsUint32 (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_LONG(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_long val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsInt64 (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_ULONG(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_ulong val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsUint64 (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_BOOL(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_bool val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsBool (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_SIZET(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      size_t val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsUint32 (val); /* FIXME: Proper type? */ \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_HALF(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_half val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsUint16 (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_FLOAT(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_float val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsFloat (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_DOUBLE(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_double val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsDouble (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_STRING(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      nsCString val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+          rv = variant->SetAsACString (val); \
+    }
+
+#define GETINFO_MEDIATOR_EXTRA_FUN_IMAGE_FORMAT(extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cl_image_format val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) { \
+          nsIWritableVariant* res; \
+          rv = WebCL_imageFormatToVariant (cx, val, (nsIVariant**)&res); \
+          variant = already_AddRefed<nsIWritableVariant>(res); \
+      } \
+    }
+
+/**
+ * The following macros implement getInfo calls and type conversions of the
+ * resulting values to nsIVariants for WebCL* object types.
+ * \param cltype An internal OpenCL type of the resulting value.
+ * \param Twebcl Respective WebCL* class of the resulting value.
+ * Other params are similar to previous macros.
+ */
+#define GETINFO_MEDIATOR_EXTRA_FUN_OBJECT(cltype,Twebcl,extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      cltype val = 0; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) { \
+        nsCOMPtr<Twebcl> xpcObj; \
+        rv = Twebcl::getInstance (val, getter_AddRefs(xpcObj), lib); \
+        if (NS_FAILED (rv)) break; \
+        rv = variant->SetAsInterface (NS_GET_IID (I##Twebcl), xpcObj); \
+      } \
+    }
+
+/**
+ * The following macros implement getInfo calls and type conversions of the
+ * resulting values to nsIVariants for vector types types.
+ * There must be a compatible specialization of WebCL_convertVectorToJSArrayInVariant
+ * for the vector type.
+ * \param Tvector The type of vector items.
+ * \param Ttypes The type of expected interpretation of the data as an enum from
+ * clwrappertypes.h .
+ * Other params are similar to previous macros.
+ *
+ * \see WebCL_convertVectorToJSArrayInVariant
+ * \see clwrappertypes.h
+ */
+#define GETINFO_MEDIATOR_EXTRA_FUN_VECTOR(Tvector,Ttypes,extra,name,lib,infoFunc,internal,variant,err,rv) { \
+      nsTArray<Tvector> val; \
+      err = lib->infoFunc (internal, extra, name, val); \
+      if (CL_SUCCEEDED (err)) \
+        rv = WebCL_convertVectorToJSArrayInVariant (cx, val, Ttypes, (nsIVariant**)&variant, lib); \
+    }
+
+
+/** The following macros build switch statement case labels from type enums in
+ * clwrappertypes.h using the macros defined above.
+ */
+
+#define GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_SIMPLE(extra,name,lib,infoFunc,internal,variant,err,rv) \
+    case types::BYTE: \
+    case types::CHAR: \
+        GETINFO_MEDIATOR_EXTRA_FUN_CHAR (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::UCHAR: \
+        GETINFO_MEDIATOR_EXTRA_FUN_UCHAR (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::SHORT: \
+        GETINFO_MEDIATOR_EXTRA_FUN_SHORT (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::USHORT: \
+        GETINFO_MEDIATOR_EXTRA_FUN_USHORT (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::BUILD_STATUS: \
+    case types::INT: \
+        GETINFO_MEDIATOR_EXTRA_FUN_INT (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::ADRESSING_MODE: \
+    case types::CHANNEL_ORDER: \
+    case types::CHANNEL_TYPE: \
+    case types::COMMAND_TYPE: \
+    case types::DEVICE_LOCAL_MEM_TYPE: \
+    case types::DEVICE_MEM_CACHE_TYPE: \
+    case types::FILTER_MODE: \
+    case types::GL_OBJECT_TYPE: \
+    case types::MEM_OBJECT_TYPE: \
+    case types::UINT: \
+        GETINFO_MEDIATOR_EXTRA_FUN_UINT (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::LONG: \
+        GETINFO_MEDIATOR_EXTRA_FUN_LONG (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::COMMAND_QUEUE_PROPERTIES: \
+    case types::DEVICE_EXEC_CAPABILITIES: \
+    case types::DEVICE_FP_CONFIG: \
+    case types::DEVICE_TYPE: \
+    case types::MAP_FLAGS: \
+    case types::MEM_FLAGS: \
+    case types::ULONG: \
+        GETINFO_MEDIATOR_EXTRA_FUN_ULONG (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::BOOL: \
+        GETINFO_MEDIATOR_EXTRA_FUN_BOOL (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::SIZE_T: \
+        GETINFO_MEDIATOR_EXTRA_FUN_SIZET (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::HALF: \
+        GETINFO_MEDIATOR_EXTRA_FUN_HALF (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::FLOAT: \
+        GETINFO_MEDIATOR_EXTRA_FUN_FLOAT (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::DOUBLE: \
+        GETINFO_MEDIATOR_EXTRA_FUN_DOUBLE (extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::IMAGE_FORMAT: \
+        GETINFO_MEDIATOR_EXTRA_FUN_IMAGE_FORMAT (extra, name, lib, infoFunc, internal, variant, err, rv); break;
+
+#define GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_STRINGS(extra,name,lib,infoFunc,internal,variant,err,rv) \
+    case types::STRING: \
+        GETINFO_MEDIATOR_EXTRA_FUN_STRING (extra, name, lib, infoFunc, internal, variant, err, rv); break;
+
+#define GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_OBJECTS(extra,name,lib,infoFunc,internal,variant,err,rv) \
+    case types::PLATFORM: \
+      GETINFO_MEDIATOR_EXTRA_FUN_OBJECT (cl_platform_id, WebCLPlatform, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::DEVICE: \
+      GETINFO_MEDIATOR_EXTRA_FUN_OBJECT (cl_device_id, WebCLDevice, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::CONTEXT: \
+      GETINFO_MEDIATOR_EXTRA_FUN_OBJECT (cl_context, WebCLContext, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::COMMAND_QUEUE: \
+      GETINFO_MEDIATOR_EXTRA_FUN_OBJECT (cl_command_queue, WebCLCommandQueue, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::MEMORY_OBJECT: \
+      GETINFO_MEDIATOR_EXTRA_FUN_OBJECT (cl_mem, WebCLMemoryObject, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::PROGRAM: \
+      GETINFO_MEDIATOR_EXTRA_FUN_OBJECT (cl_program, WebCLProgram, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::KERNEL: \
+      GETINFO_MEDIATOR_EXTRA_FUN_OBJECT (cl_kernel, WebCLKernel, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::EVENT: \
+      GETINFO_MEDIATOR_EXTRA_FUN_OBJECT (cl_event, WebCLEvent, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::SAMPLER: \
+      GETINFO_MEDIATOR_EXTRA_FUN_OBJECT (cl_sampler, WebCLSampler, extra, name, lib, infoFunc, internal, variant, err, rv); break;
+
+#define GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_VECTORS_SIMPLE(extra,name,lib,infoFunc,internal,variant,err,rv) \
+    case types::BYTE_V: \
+    case types::CHAR_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_char, types::CHAR_V, extra, name, lib, infoFunc, internal, variant, err, rv); \
+        break; \
+    case types::UCHAR_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_uchar, types::UCHAR_V, extra, name, lib, infoFunc, internal, variant, err, rv); \
+        break; \
+    case types::SHORT_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_short, types::SHORT_V, extra, name, lib, infoFunc, internal, variant, err, rv); \
+        break; \
+    case types::USHORT_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_ushort, types::USHORT_V, extra, name, lib, infoFunc, internal, variant, err, rv); \
+        break; \
+    case types::CONTEXT_PROPERTIES: \
+    case types::INT_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_int, types::INT_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::UINT_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_uint, types::UINT_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::LONG_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_long, types::LONG_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::ULONG_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_ulong, types::ULONG_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::BOOL_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_bool, types::BOOL_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::SIZE_T_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (size_t, types::SIZE_T_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::HALF_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_half, types::HALF_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::FLOAT_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_float, types::FLOAT_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::DOUBLE_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_double, types::DOUBLE_V, extra, name, lib, infoFunc, internal, variant, err, rv); break;
+
+#define GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_VECTORS_STRINGS(extra,name,lib,infoFunc,internal,variant,err,rv) \
+    case types::STRING_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (nsCString, types::STRING_V, extra, name, lib, infoFunc, internal, variant, err, rv); break;
+
+#define GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_VECTORS_OBJECTS(extra,name,lib,infoFunc,internal,variant,err,rv) \
+    case types::PLATFORM_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_platform_id, types::PLATFORM_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::DEVICE_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_device_id, types::DEVICE_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::CONTEXT_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_context, types::CONTEXT_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::COMMAND_QUEUE_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_command_queue, types::COMMAND_QUEUE_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::MEMORY_OBJECT_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_mem, types::MEMORY_OBJECT_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::PROGRAM_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_program, types::PROGRAM_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::KERNEL_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_kernel, types::KERNEL_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::EVENT_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_event, types::EVENT_V, extra, name, lib, infoFunc, internal, variant, err, rv); break; \
+    case types::SAMPLER_V: \
+        GETINFO_MEDIATOR_EXTRA_FUN_VECTOR (cl_sampler, types::SAMPLER_V, extra, name, lib, infoFunc, internal, variant, err, rv); break;
+
+
+#define GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_VECTORS(extra,name,lib,infoFunc,internal,variant,err,rv) \
+    GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_VECTORS_SIMPLE (extra, name, lib, infoFunc, internal, variant, err, rv) \
+    GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_VECTORS_STRINGS (extra, name, lib, infoFunc, internal, variant, err, rv) \
+    GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_VECTORS_OBJECTS (extra, name, lib, infoFunc, internal, variant, err, rv)
+
+#define GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_ALL(extra,name,lib,infoFunc,internal,variant,err,rv) \
+    GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_SIMPLE (extra, name, lib, infoFunc, internal, variant, err, rv) \
+    GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_STRINGS (extra, name, lib, infoFunc, internal, variant, err, rv) \
+    GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_OBJECTS (extra, name, lib, infoFunc, internal, variant, err, rv) \
+    GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_VECTORS (extra, name, lib, infoFunc, internal, variant, err, rv)
+
+
+/** This macro implements the switch statement for getXInfo using the
+ * GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER macros.
+ * \param aName The property name enum.
+ * \param aType The property type, e.g. types::UINT.
+ * \param aFunc The getInfo helper function, e.g. ContextWrapper::getInfo.
+ * \param aInternal Internal OpenCL resource.
+ * \param aVariant An nsIVariant instance.
+ * \param aErr A variable for the OpenCL error code.
+ * \param aNSErr A variable for the NS error code (nsresult).
+ * Note: Function return value must be nsresult.
+ */
+#define WEBCL_GETINFO_MEDIATOR_EXTRA_SWITCH(aExtra,aName,aType,aLib,aFunc,aInternal,aVariant,aErr,aNSErr) do{ \
+    switch (aType) { \
+      GETINFO_MEDIATOR_EXTRA_SWITCH_HELPER_FUN_ALL (aExtra, aName, aLib, aFunc, aInternal, aVariant, aErr, aNSErr)\
+      default: {\
+        D_LOG (LOG_LEVEL_ERROR, "Requested unsupported property %d.", aName); \
+        WebCL_reportJSError (cx, "%s: Requested unsupported property %d with type %d.", __FUNCTION__, aName, aType); \
+        return WEBCL_XPCOM_ERROR; /*NS_ERROR_INVALID_ARG;*/ \
+      } \
+    }\
+    if (CL_FAILED (aErr) || NS_FAILED (aNSErr)) { \
+      D_LOG (LOG_LEVEL_ERROR, "%s failed, clError: %d, mozError: %d", \
+      __FUNCTION__, aErr, aNSErr); \
+      WebCL_reportJSError (cx, "%s failed with error %d.", __FUNCTION__, aErr); \
+      return WEBCL_XPCOM_ERROR; /*NS_ERROR_FAILURE;*/ \
+    } \
+  }while(0)
+
+
+
+#endif // _WEBCL_INTERNAL_H_
+
diff -r 450143d2d810 browser/components/webcl/src/WebCL_libcl.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCL_libcl.cpp	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,314 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#include "WebCL_libcl.h"
+
+#include "WebCLCommon.h"
+
+#include <cstdlib>
+#include <cstring>
+#include <cctype>
+#include <new>
+
+#include <prlink.h>
+#include <prmem.h>
+#include <prerror.h>
+
+#include <nsCOMPtr.h>
+
+#include "WebCL_clsymbols.h"
+
+
+static bool loadCLLibrary (WebCL_LibCL* instance, PRLibrary* libHndl);
+
+
+NS_IMPL_THREADSAFE_ISUPPORTS0(WebCL_LibCL)
+
+
+WebCL_LibCL::WebCL_LibCL ()
+  : nsISupports(),
+    symbols(new WebCL_CLSymbols),
+    m_libName(0),
+    m_libHandle(0)
+{
+  D_METHOD_START;
+
+  memset ((void*)symbols, 0, sizeof(WebCL_CLSymbols));
+}
+
+
+WebCL_LibCL::~WebCL_LibCL ()
+{
+  D_METHOD_START;
+
+  if (m_libHandle)
+    unload (this);
+
+  if (m_libName)
+    delete (m_libName);
+
+  if (symbols)
+    delete (symbols);
+}
+
+char const* const WebCL_LibCL::libName () const
+{
+  return m_libName;
+}
+
+// Release the retun value with PR_FREEIF
+static char* getPRErrorText ()
+{
+  PRInt32 errTextLen = PR_GetErrorTextLength ();
+  char *rv = (char*)PR_MALLOC (errTextLen + 1);
+  if (rv)
+  {
+    rv[0] = '\0';
+    (void)PR_GetErrorText (rv);
+  }
+
+  return rv;
+}
+
+/* static */
+bool WebCL_LibCL::load (char const* aLibName, WebCL_LibCL** aInstanceOut,
+                        nsCString* aErrorMessageOut)
+{
+  D_METHOD_START;
+
+  if (!aLibName)
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Invalid arguments: aLibName = NULL.");
+    if (aErrorMessageOut)
+      *aErrorMessageOut = "Invalid library name: NULL";
+    return false;
+  }
+
+  // Front strip lib name
+  size_t libPathLen = strlen (aLibName);
+  char const* cleanedLibName = aLibName;
+  while (cleanedLibName < aLibName + libPathLen && isspace(*cleanedLibName))
+    ++cleanedLibName;
+
+  if (cleanedLibName[0] == '\0')
+  {
+    // Empty name now allowed here, handle default library on a higher level
+    D_LOG (LOG_LEVEL_ERROR, "Invalid arguments: no library name given.");
+    if (aErrorMessageOut)
+      *aErrorMessageOut = "Invalid library name: \"\"";
+    return false;
+  }
+
+  char* systemName = PR_GetLibraryName (NULL, cleanedLibName);
+  D_LOG (LOG_LEVEL_DEBUG, "system name for library %s: %s", cleanedLibName, systemName);
+
+  nsCOMPtr<WebCL_LibCL> instance (new (std::nothrow) WebCL_LibCL);
+  instance->m_libName = strdup (systemName);
+
+  PRLibrary* libHndl = PR_LoadLibrary (systemName);
+  PR_FreeLibraryName (systemName);
+
+  char* errText = 0;
+
+  if (!libHndl)
+  {
+    // Perhaps PR_GetLibraryName failed?
+    errText = getPRErrorText ();
+    D_LOG (LOG_LEVEL_ERROR, "Failed to load library by system name %s: %s",
+           instance->m_libName, errText);
+    D_LOG (LOG_LEVEL_DEBUG, " (prerr: %d oserr: %d)", PR_GetError(), PR_GetOSError());
+    PR_FREEIF (errText);
+    errText = 0;
+
+    // TODO: check if this is even sane?
+    libHndl = PR_LoadLibrary (cleanedLibName);
+    if (!libHndl)
+    {
+      // Failed to load the library.
+      errText = getPRErrorText ();
+      D_LOG (LOG_LEVEL_ERROR, "Failed to load library %s: %s", cleanedLibName, errText);
+      D_LOG (LOG_LEVEL_DEBUG, "  (prerr: %d oserr: %d)", PR_GetError(), PR_GetOSError());
+      if (aErrorMessageOut)
+        *aErrorMessageOut = errText;
+
+      PR_FREEIF (errText);
+
+      return false;
+    }
+
+    instance->m_libName = strdup (cleanedLibName);
+  }
+
+  instance->m_libHandle = libHndl;
+  if (!loadCLLibrary (instance, libHndl))
+  {
+    D_LOG (LOG_LEVEL_ERROR, "Failed to load library %s: required symbols missing.", instance->m_libName);
+    if (aErrorMessageOut)
+      *aErrorMessageOut = "Required symbols not found.";
+
+    return false;
+  }
+
+  if (aInstanceOut)
+  {
+    NS_ADDREF (*aInstanceOut = instance);
+  }
+
+  return true;
+}
+
+
+/* static */
+void WebCL_LibCL::unload (WebCL_LibCL* aInstance)
+{
+  D_METHOD_START;
+
+  if (!(aInstance && aInstance->m_libHandle))
+    return;
+
+  if (PR_UnloadLibrary (aInstance->m_libHandle) == PR_FAILURE)
+  {
+    char *errText = getPRErrorText ();
+    D_LOG (LOG_LEVEL_WARNING, "Failed to unload library %s: %s", aInstance->m_libName, errText);
+    D_LOG (LOG_LEVEL_DEBUG, "  (prerr: %d oserr: %d)", PR_GetError(), PR_GetOSError());
+    PR_FREEIF (errText);
+  }
+  else
+  {
+    D_LOG (LOG_LEVEL_DEBUG, "Unloaded library %s", aInstance->m_libName);
+  }
+}
+
+
+#define LOAD_CL_SYM(name,required) \
+  instance->symbols->name = (WebCL_CLSymbols::_##name##_t) PR_FindSymbol (libHndl, #name); \
+  if (!instance->symbols->name) { \
+    if (required) { \
+      D_LOG (LOG_LEVEL_ERROR, "Failed to load symbol %s.", #name); \
+      rv = false; \
+    } else { \
+      D_LOG (LOG_LEVEL_WARNING, "Failed to load symbol %s.", #name); \
+    } \
+  } else D_LOG (LOG_LEVEL_DEBUG, "Loaded symbol %s.", #name); \
+
+
+static bool loadCLLibrary (WebCL_LibCL* instance, PRLibrary* libHndl)
+{
+  D_METHOD_START;
+  if (!(instance && instance->symbols && libHndl))
+    return false;
+
+  bool rv = true;
+
+  LOAD_CL_SYM (clGetPlatformIDs, true)
+  LOAD_CL_SYM (clGetPlatformInfo, true)
+  LOAD_CL_SYM (clGetDeviceIDs, true)
+  LOAD_CL_SYM (clGetDeviceInfo, true)
+  LOAD_CL_SYM (clCreateContext, true)
+  LOAD_CL_SYM (clCreateContextFromType, true)
+  LOAD_CL_SYM (clRetainContext, true)
+  LOAD_CL_SYM (clReleaseContext, true)
+  LOAD_CL_SYM (clGetContextInfo, true)
+  LOAD_CL_SYM (clCreateCommandQueue, true)
+  LOAD_CL_SYM (clRetainCommandQueue, true)
+  LOAD_CL_SYM (clReleaseCommandQueue, true)
+  LOAD_CL_SYM (clGetCommandQueueInfo, true)
+  LOAD_CL_SYM (clCreateBuffer, true)
+  LOAD_CL_SYM (clCreateSubBuffer, true)
+  LOAD_CL_SYM (clCreateImage2D, true)
+  LOAD_CL_SYM (clCreateImage3D, true)
+  LOAD_CL_SYM (clRetainMemObject, true)
+  LOAD_CL_SYM (clReleaseMemObject, true)
+  LOAD_CL_SYM (clGetSupportedImageFormats, true)
+  LOAD_CL_SYM (clGetMemObjectInfo, true)
+  LOAD_CL_SYM (clGetImageInfo, true)
+  LOAD_CL_SYM (clSetMemObjectDestructorCallback, true)
+  LOAD_CL_SYM (clCreateSampler, true)
+  LOAD_CL_SYM (clRetainSampler, true)
+  LOAD_CL_SYM (clReleaseSampler, true)
+  LOAD_CL_SYM (clGetSamplerInfo, true)
+  LOAD_CL_SYM (clCreateProgramWithSource, true)
+  LOAD_CL_SYM (clCreateProgramWithBinary, true)
+  LOAD_CL_SYM (clRetainProgram, true)
+  LOAD_CL_SYM (clReleaseProgram, true)
+  LOAD_CL_SYM (clBuildProgram, true)
+  LOAD_CL_SYM (clUnloadCompiler, true)
+  LOAD_CL_SYM (clGetProgramInfo, true)
+  LOAD_CL_SYM (clGetProgramBuildInfo, true)
+  LOAD_CL_SYM (clCreateKernel, true)
+  LOAD_CL_SYM (clCreateKernelsInProgram, true)
+  LOAD_CL_SYM (clRetainKernel, true)
+  LOAD_CL_SYM (clReleaseKernel, true)
+  LOAD_CL_SYM (clSetKernelArg, true)
+  LOAD_CL_SYM (clGetKernelInfo, true)
+  LOAD_CL_SYM (clGetKernelWorkGroupInfo, true)
+  LOAD_CL_SYM (clWaitForEvents, true)
+  LOAD_CL_SYM (clGetEventInfo, true)
+  LOAD_CL_SYM (clCreateUserEvent, true)
+  LOAD_CL_SYM (clRetainEvent, true)
+  LOAD_CL_SYM (clReleaseEvent, true)
+  LOAD_CL_SYM (clSetUserEventStatus, true)
+  LOAD_CL_SYM (clSetEventCallback, true)
+  LOAD_CL_SYM (clGetEventProfilingInfo, true)
+  LOAD_CL_SYM (clFlush, true)
+  LOAD_CL_SYM (clFinish, true)
+  LOAD_CL_SYM (clEnqueueReadBuffer, true)
+  LOAD_CL_SYM (clEnqueueReadBufferRect, true)
+  LOAD_CL_SYM (clEnqueueWriteBuffer, true)
+  LOAD_CL_SYM (clEnqueueWriteBufferRect, true)
+  LOAD_CL_SYM (clEnqueueCopyBuffer, true)
+  LOAD_CL_SYM (clEnqueueCopyBufferRect, true)
+  LOAD_CL_SYM (clEnqueueReadImage, true)
+  LOAD_CL_SYM (clEnqueueWriteImage, true)
+  LOAD_CL_SYM (clEnqueueCopyImage, true)
+  LOAD_CL_SYM (clEnqueueCopyImageToBuffer, true)
+  LOAD_CL_SYM (clEnqueueCopyBufferToImage, true)
+  LOAD_CL_SYM (clEnqueueMapBuffer, true)
+  LOAD_CL_SYM (clEnqueueMapImage, true)
+  LOAD_CL_SYM (clEnqueueUnmapMemObject, true)
+  LOAD_CL_SYM (clEnqueueNDRangeKernel, true)
+  LOAD_CL_SYM (clEnqueueTask, true)
+  LOAD_CL_SYM (clEnqueueNativeKernel, true)
+  LOAD_CL_SYM (clEnqueueMarker, true)
+  LOAD_CL_SYM (clEnqueueWaitForEvents, true)
+  LOAD_CL_SYM (clEnqueueBarrier, true)
+  LOAD_CL_SYM (clGetExtensionFunctionAddress, true)
+
+  LOAD_CL_SYM (clCreateFromGLBuffer, false)
+  LOAD_CL_SYM (clCreateFromGLTexture2D, false)
+  LOAD_CL_SYM (clCreateFromGLTexture3D, false)
+  LOAD_CL_SYM (clCreateFromGLRenderbuffer, false)
+  LOAD_CL_SYM (clGetGLObjectInfo, false)
+  LOAD_CL_SYM (clGetGLTextureInfo, false)
+  LOAD_CL_SYM (clEnqueueAcquireGLObjects, false)
+  LOAD_CL_SYM (clEnqueueReleaseGLObjects, false)
+  LOAD_CL_SYM (clGetGLContextInfoKHR, false)
+
+  return rv;
+}
diff -r 450143d2d810 browser/components/webcl/src/WebCL_libcl.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/WebCL_libcl.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,62 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+#ifndef _WEBCL_LIBCL_H_
+#define _WEBCL_LIBCL_H_
+
+#include "nsISupports.h"
+#include "nsStringAPI.h"
+
+struct WebCL_CLSymbols;
+class PRLibrary;
+
+class WebCL_LibCL : public nsISupports
+{
+public:
+  NS_DECL_ISUPPORTS
+  virtual ~WebCL_LibCL ();
+
+  char const* const libName () const;
+
+  static bool load (char const* aLibPath, WebCL_LibCL** aInstanceOut,
+                    nsCString* aErrorMessageOut = 0);
+
+  WebCL_CLSymbols* symbols;
+
+private:
+  static void unload (WebCL_LibCL* aLib);
+
+  WebCL_LibCL ();
+
+  char const* m_libName;
+  PRLibrary* m_libHandle;
+};
+
+
+#endif //_WEBCL_LIBCL_H_
diff -r 450143d2d810 browser/components/webcl/src/instance_registry.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/webcl/src/instance_registry.h	Mon Sep 03 14:02:08 2012 +0300
@@ -0,0 +1,87 @@
+/*
+ * This file is part of WebCL – JavaScript bindings for OpenCL
+ * http://webcl.nokiaresearch.com/
+ *
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Jari Nikara  ;jari.nikara@nokia.com;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * The package is based on a published Khronos OpenCL 1.1 Specification,
+ * see http://www.khronos.org/opencl/.
+ *
+ * OpenCL is a trademark of Apple Inc.
+ */
+
+/** \file instance_registry.h
+ * InstanceRegistry class definition.
+ */
+
+#ifndef _INSTANCE_REGISTRY_H_
+#define _INSTANCE_REGISTRY_H_
+
+#include <map>
+#include "WebCLLogger.h"
+
+
+/** This template class provides an instance registry for WebCL classes.
+ * Many WebCL classes contain some internal information that provides the actual
+ * identity of the instance in the form of a reference to some external entity.
+ * In certain occasions it is necessary to find a WebCL instance by the bare
+ * external identity reference that may come from e.g. an external library.
+ */
+template <class Tid, class Tinstance>
+class InstanceRegistry {
+  public:
+    InstanceRegistry () : mInstances () { }
+    ~InstanceRegistry () { }
+
+    bool add (Tid aId, Tinstance aInstance)
+    {
+      D_LOG (LOG_LEVEL_DEBUG, "Added instance mapping %p:%p", aId, aInstance);
+      return mInstances.insert (std::make_pair (aId, aInstance)).second;
+    }
+
+    bool remove (Tid aId)
+    {
+      D_LOG (LOG_LEVEL_DEBUG, "Removed instance mapping %p", aId);
+      return mInstances.erase (aId) != 0;
+    }
+
+    bool findById (Tid aId, Tinstance* aInstance)
+    {
+      if (!aInstance)
+        return false;
+      typename std::map<Tid, Tinstance>::iterator i = mInstances.find (aId);
+      if (i != mInstances.end ())
+      {
+        *aInstance = i->second;
+        return true;
+      }
+      return false;
+    }
+
+  private:
+    /// Copying is not allowed.
+    InstanceRegistry (InstanceRegistry const&);
+    /// Assignment is not allowed.
+    InstanceRegistry& operator= (InstanceRegistry const&);
+
+    std::map <Tid, Tinstance> mInstances;
+};
+
+#endif // _INSTANCE_REGISTRY_H_
diff -r 450143d2d810 browser/installer/package-manifest.in
--- a/browser/installer/package-manifest.in	Fri Aug 24 15:28:46 2012 -0700
+++ b/browser/installer/package-manifest.in	Mon Sep 03 14:02:08 2012 +0300
@@ -301,6 +301,9 @@
 @BINPATH@/components/zipwriter.xpt
 @BINPATH@/components/telemetry.xpt
 
+; Nokia WebCL
+@BINPATH@/components/webcl.xpt
+
 ; JavaScript components
 @BINPATH@/components/ConsoleAPI.manifest
 @BINPATH@/components/ConsoleAPI.js
diff -r 450143d2d810 browser/makefiles.sh
--- a/browser/makefiles.sh	Fri Aug 24 15:28:46 2012 -0700
+++ b/browser/makefiles.sh	Mon Sep 03 14:02:08 2012 +0300
@@ -37,6 +37,9 @@
 browser/components/shell/src/Makefile
 browser/components/tabview/Makefile
 browser/components/thumbnails/Makefile
+browser/components/webcl/Makefile
+browser/components/webcl/public/Makefile
+browser/components/webcl/src/Makefile
 browser/devtools/Makefile
 browser/devtools/debugger/Makefile
 browser/devtools/highlighter/Makefile
